SlideShare une entreprise Scribd logo
Debugging Flutter apps
MAD
Debugging
• In computer programming and software development, debugging is
the process of finding and resolving bugs within computer programs,
software, or systems.
Debugging Flutter apps
• variety of tools and features to help debug Flutter applications
• DevTools, a suite of performance and profiling tools that run in a browser.
• Android Studio/IntelliJ, and VS Code (enabled with the Flutter and Dart
plugins) support a built-in source-level debugger with the ability to set
breakpoints, step through code, and examine values.
• Flutter inspector, a widget inspector available in DevTools, and also directly
from Android Studio and IntelliJ (enabled with the Flutter plugin). The
inspector allows you to examine a visual representation of the widget tree,
inspect individual widgets and their property values, enable the performance
overlay, and more
DevTools
• source-level debugger
• widget inspector that displays a visual widget tree, and “widget
select” mode where you select a widget in the app and it drills down
to that widget in the tree
• memory profiler
• timeline view that supports tracing, and importing and exporting
trace information
• logging view
Breakpoints, Dart analyzer and Logging
• Breakpoints are one of the most important debugging techniques in
your developer's toolbox. You set breakpoints wherever you want to
pause debugger execution.
• Flutter enabled IDE/editor, the Dart analyzer is already checking your
code and looking for possible mistakes.
• from the command line, test your code with flutter analyze.
• You set logging up programmatically then view the output in the
DevTools logging view, or in the console.
Debugging application layers
• Flutter was designed with a layered architecture that includes widget,
rendering, and painting layers.
• Flutter widget inspector provides a visual representation of the
widget tree, but if you want a greater level of detail, or you want a
verbose text-based dump of the widget, layer, or render trees
• Widget tree
• Render tree
• Layer tree
• Semantics tree
• Scheduling
Debugging application layers
• To dump the state of the Widgets library, call debugDumpApp().
• If you are trying to debug a layout issue, then the Widgets layer’s tree
might be insufficiently detailed. In that case, you can dump the rendering
tree by calling debugDumpRenderTree().
• if you are trying to debug a compositing issue, you can use
debugDumpLayerTree().
• You can also obtain a dump of the Semantics tree (the tree presented to
the system accessibility APIs) using debugDumpSemanticsTree().
• To find out where your events happen relative to the frame’s begin/end,
you can toggle the debugPrintBeginFrameBanner and the
debugPrintEndFrameBanner booleans to print the beginning and end of
the frames to the console.
Debug flags: layout
• You can also debug a layout problem visually, by setting
debugPaintSizeEnabled to true. This is a boolean from the rendering
library.
• //add import to rendering library
• import 'package:flutter/rendering.dart';
• void main() {
• debugPaintSizeEnabled=true;
• runApp(MyApp());
• }
Debugging animations
• Debug animations is to slow them down. You can do this using the
Slow Animations button in DevTools’ Inspector view, which slows
down the animation by 5x.
• Set the timeDilation variable (from the scheduler library) to a number
greater than 1.0, for instance, 50.0.
• It’s best to only set this once on app startup.
Debug flags: performance
• Flutter provides a wide variety of debug flags and functions to help
you debug your app at various points along the development cycle.
• To use these features, you must compile in debug mode.
• debugDumpRenderTree()
• debugPaintLayerBordersEnabled
• debugRepaintRainbowEnabled
• debugPrintMarkNeedsLayoutStacks
• debugPrintMarkNeedsPaintStacks
Measuring app startup time
• To gather detailed information about the time it takes for your Flutter
app to start, you can run the flutter run command with the trace-
startup and profile options.
• The trace output is saved as a JSON file called start_up_info.json
under the build directory of your Flutter project.
• The output lists the elapsed time from app startup to these trace
events
• Time to enter the Flutter engine code.
• Time to render the first frame of the app.
• Time to initialize the Flutter framework.
• Time to complete the Flutter framework initialization.
Flutter's build modes
• Flutter tooling supports three modes when compiling your app, and a
headless mode for testing.
• Use debug mode during development, when you want to use hot
reload.
• Use profile mode when you want to analyze performance.
• Use release mode when you are ready to release your app.
Debug Mode
• Debug mode for mobile apps mean that:
• Assertions are enabled.
• Service extensions are enabled.
• Compilation is optimized for fast development and run cycles (but not for
execution speed, binary size, or deployment).
• Debugging is enabled, and tools supporting source level debugging (such as
DevTools) can connect to the process.
• Debug mode for a web app means that:
• The build is not minified and tree shaking has not been performed.
• The app is compiled with the dartdevc compiler for easier debugging.
Release
• release mode for deploying the app, when you want maximum optimization and
minimal footprint size. For mobile, release mode (which is not supported on the
simulator or emulator), means that:
• Assertions are disabled.
• Debugging information is stripped out.
• Debugging is disabled.
• Compilation is optimized for fast startup, fast execution, and small package sizes.
• Service extensions are disabled.
• Release mode for a web app means that:
• The build is minified and tree shaking has been performed.
• The app is compiled with the dart2js compiler for best performance.
Profile
• profile mode, some debugging ability is maintained—enough to profile your app’s performance.
Profile mode is disabled on the emulator and simulator, because their behavior is not
representative of real performance. On mobile, profile mode is similar to release mode, with the
following differences:
• Some service extensions, such as the one that enables the performance overlay, are enabled.
• Tracing is enabled, and tools supporting source-level debugging (such as DevTools) can connect
to the process.
• Profile mode for a web app means that:
• The build is not minified but tree shaking has been performed.
• The app is compiled with the dart2js compiler.
Common Flutter errors
• several frequently-encountered Flutter framework errors and gives
suggestions on how to resolve them
• A RenderFlex overflowed…
• RenderFlex overflow is one of the most frequently encountered
Flutter framework errors, and you probably have run into it already.
• The error often occurs when a Column or Row has a child widget that
is not constrained in its size.
• Well, you need to make sure the Column won’t attempt to be wider
than it can be. To achieve this, you need to constrain its width. One
way to do it is to wrap the Column in an Expanded widget
RenderBox was not laid out
• While this error is pretty common, it’s often a side effect of a primary
error occurring earlier in the rendering pipeline.
• Usually, the issue is related to violation of box constraints, and it
needs to be solved by providing more information to Flutter about
how you’d like to constrain the widgets in question
• The RenderBox was not laid out error is often caused by one of two
other errors:
• ‘Vertical viewport was given unbounded height’
• ‘An InputDecorator…cannot have an unbounded width’
Vertical viewport was given unbounded height
• This is another common layout error you could run into while creating
a UI in your Flutter app.
• The error is often caused when a ListView (or other kinds of scrollable
widgets such as GridView) is placed inside a Column.
• To fix this error, specify how tall the ListView should be. To make it as
tall as the remaining space in the Column, wrap it using an Expanded
widget (see the example below). Otherwise, specify an absolute
height using a SizedBox widget or a relative height using a Flexible
widget.
Incorrect use of ParentData widget
• This error is about missing an expected parent widget.
• While Flutter’s widgets are generally flexible in how they can be
composed together in a UI, a small subset of those widgets expect
specific parent widgets.
• The fix should be obvious once you know which parent widget is
missing.
Handling errors in Flutter
• Flutter framework catches errors that occur during callbacks triggered
by the framework itself, including errors encountered during the
build, layout, and paint phases.
• Errors that don’t occur within Flutter’s callbacks can’t be caught by
the framework, but you can handle them by setting up a Zone.
• By default, a Zone only prints errors and does nothing else.
• All errors caught by Flutter are routed to the FlutterError.onError
handler.
• By default, this calls FlutterError.dumpErrorToConsole, which, as you
might guess, dumps the error to the device logs.
Handling errors in Flutter (Cont…)
• When running from an IDE, the inspector overrides this so that errors
can also be routed to the IDE’s console, allowing you to inspect the
objects mentioned in the message.
• When an error occurs during the build phase, the ErrorWidget.builder
callback is invoked to build the widget that is used instead of the one
that failed.
• By default, in debug mode this shows an error message in red, and in
release mode this shows a gray background.
Errors caught by Flutter
• import 'dart:io';
• import 'package:flutter/foundation.dart';
• import 'package:flutter/material.dart';
• void main() {
• FlutterError.onError = (FlutterErrorDetails details) {
• FlutterError.dumpErrorToConsole(details);
• if (kReleaseMode)
• exit(1);
• };
• runApp(MyApp());
• }
• // rest of `flutter create` code...
This handler can also be used to report errors to a logging
service.
To make your application quit immediately any time an error is
caught by Flutter in release mode
Define a custom error widget for build phase
errors
• class MyApp extends StatelessWidget {
• ...
• @override
• Widget build(BuildContext context) {
• return MaterialApp(
• ...
• builder: (BuildContext context, Widget widget) {
• Widget error = Text('...rendering error...');
• if (widget is Scaffold || widget is Navigator)
• error = Scaffold(body: Center(child: error));
• ErrorWidget.builder = (FlutterErrorDetails errorDetails) => error;
• return widget;
• },
• );
• }
• }
To define a customized error widget that displays whenever the builder fails to build a widget, use MaterialApp.builder.
Errors not caught by Flutter
• OutlinedButton(
• child: Text('Click me!'),
• onPressed: () async {
• final channel = const MethodChannel('crashy-custom-channel');
• await channel.invokeMethod('blah');
• },
• ),
Consider an onPressed callback that invokes an asynchronous function, such as MethodChannel.invokeMethod
• If invokeMethod throws an error, it won’t be forwarded to
FlutterError.onError. Instead, it’s forwarded to the Zone where runApp was
run.
• To catch such an error, use runZonedGuarded.
• import 'dart:async';
• void main() {
• runZonedGuarded(() {
• runApp(MyApp());
• }, (Object error, StackTrace stack) {
• myBackend.sendError(error, stack);
• });
• }
Errors not caught by Flutter (Cont..)
• Note that if in your app you call WidgetsFlutterBinding.ensureInitialized()
manually to perform some initialization before calling runApp (e.g.
Firebase.initializeApp()), you must call
WidgetsFlutterBinding.ensureInitialized() inside runZonedGuarded:
• runZonedGuarded(() async {
• WidgetsFlutterBinding.ensureInitialized();
• await Firebase.initializeApp();
• runApp(MyApp());
• }
Errors not caught by Flutter (Cont..)
Note: Error handling wouldn’t work if WidgetsFlutterBinding.ensureInitialized() was called from the outside
Handling all types of errors
• import 'dart:io';
• import 'package:flutter/foundation.dart';
• import 'package:flutter/material.dart';
• void main() {
• runZonedGuarded(() async {
• WidgetsFlutterBinding.ensureInitialized();
• await myErrorsHandler.initialize();
• FlutterError.onError = (FlutterErrorDetails details) {
• FlutterError.dumpErrorToConsole(details);
• myErrorsHandler.onError(details);
• exit(1);
• };
• runApp(MyApp());
• }, (Object error, StackTrace stack) {
• myErrorsHandler.onError(error, stack);
• exit(1);
• });
• }
• class MyApp extends StatelessWidget {
• @override
• Widget build(BuildContext context) {
• return MaterialApp(
• builder: (BuildContext context, Widget widget) {
• Widget error = Text('...rendering error...');
• if (widget is Scaffold || widget is Navigator)
• error = Scaffold(body: Center(child: error));
• ErrorWidget.builder = (FlutterErrorDetails errorDetails) => error;
• return widget;
• },
• );
• }
• }
you want to exit application on any exception and to display a
custom error widget whenever a widget building fails
Testing Flutter apps

Contenu connexe

Similaire à Debugging MAD lecture june .pptx

Introduction to Visual Basic 6.0
Introduction to Visual Basic 6.0Introduction to Visual Basic 6.0
Introduction to Visual Basic 6.0DivyaR219113
 
Error handling and debugging in vb
Error handling and debugging in vbError handling and debugging in vb
Error handling and debugging in vbSalim M
 
Java developer trainee implementation and import
Java developer trainee implementation and importJava developer trainee implementation and import
Java developer trainee implementation and importiamluqman0403
 
IDE and Toolset For Magento Development
IDE and Toolset For Magento DevelopmentIDE and Toolset For Magento Development
IDE and Toolset For Magento DevelopmentAbid Malik
 
Analyze Your Code With Visual Studio 2015 Diagnostic Tools
Analyze Your Code With Visual Studio 2015 Diagnostic ToolsAnalyze Your Code With Visual Studio 2015 Diagnostic Tools
Analyze Your Code With Visual Studio 2015 Diagnostic ToolsKen Cenerelli
 
O365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - MaterialO365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - MaterialThomas Daly
 
Continuous Integration
Continuous IntegrationContinuous Integration
Continuous IntegrationXPDays
 
UNIT 3.1 INTRODUCTON TO IDA.ppt
UNIT 3.1 INTRODUCTON TO IDA.pptUNIT 3.1 INTRODUCTON TO IDA.ppt
UNIT 3.1 INTRODUCTON TO IDA.pptManjuAppukuttan2
 
Building of systems of automatic C/C++ code logging
Building of systems of automatic C/C++ code loggingBuilding of systems of automatic C/C++ code logging
Building of systems of automatic C/C++ code loggingPVS-Studio
 
JavaScript - Chapter 15 - Debugging Techniques
 JavaScript - Chapter 15 - Debugging Techniques JavaScript - Chapter 15 - Debugging Techniques
JavaScript - Chapter 15 - Debugging TechniquesWebStackAcademy
 
Software Bugs A Software Architect Point Of View
Software Bugs    A Software Architect Point Of ViewSoftware Bugs    A Software Architect Point Of View
Software Bugs A Software Architect Point Of ViewShahzad
 
Zendcon magento101
Zendcon magento101Zendcon magento101
Zendcon magento101Mathew Beane
 
GCP Deployment- Vertex AI
GCP Deployment- Vertex AIGCP Deployment- Vertex AI
GCP Deployment- Vertex AITriloki Gupta
 
Design Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best PracticesDesign Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best PracticesInductive Automation
 
Design Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best PracticesDesign Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best PracticesInductive Automation
 

Similaire à Debugging MAD lecture june .pptx (20)

Android dev tips
Android dev tipsAndroid dev tips
Android dev tips
 
Introduction to Visual Basic 6.0
Introduction to Visual Basic 6.0Introduction to Visual Basic 6.0
Introduction to Visual Basic 6.0
 
Error handling and debugging in vb
Error handling and debugging in vbError handling and debugging in vb
Error handling and debugging in vb
 
Java developer trainee implementation and import
Java developer trainee implementation and importJava developer trainee implementation and import
Java developer trainee implementation and import
 
IDE and Toolset For Magento Development
IDE and Toolset For Magento DevelopmentIDE and Toolset For Magento Development
IDE and Toolset For Magento Development
 
Analyze Your Code With Visual Studio 2015 Diagnostic Tools
Analyze Your Code With Visual Studio 2015 Diagnostic ToolsAnalyze Your Code With Visual Studio 2015 Diagnostic Tools
Analyze Your Code With Visual Studio 2015 Diagnostic Tools
 
tut0000021-hevery
tut0000021-heverytut0000021-hevery
tut0000021-hevery
 
tut0000021-hevery
tut0000021-heverytut0000021-hevery
tut0000021-hevery
 
Applets
AppletsApplets
Applets
 
O365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - MaterialO365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - Material
 
Continuous Integration
Continuous IntegrationContinuous Integration
Continuous Integration
 
UNIT 3.1 INTRODUCTON TO IDA.ppt
UNIT 3.1 INTRODUCTON TO IDA.pptUNIT 3.1 INTRODUCTON TO IDA.ppt
UNIT 3.1 INTRODUCTON TO IDA.ppt
 
Building of systems of automatic C/C++ code logging
Building of systems of automatic C/C++ code loggingBuilding of systems of automatic C/C++ code logging
Building of systems of automatic C/C++ code logging
 
JavaScript - Chapter 15 - Debugging Techniques
 JavaScript - Chapter 15 - Debugging Techniques JavaScript - Chapter 15 - Debugging Techniques
JavaScript - Chapter 15 - Debugging Techniques
 
Software Bugs A Software Architect Point Of View
Software Bugs    A Software Architect Point Of ViewSoftware Bugs    A Software Architect Point Of View
Software Bugs A Software Architect Point Of View
 
Zendcon magento101
Zendcon magento101Zendcon magento101
Zendcon magento101
 
GCP Deployment- Vertex AI
GCP Deployment- Vertex AIGCP Deployment- Vertex AI
GCP Deployment- Vertex AI
 
Design Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best PracticesDesign Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best Practices
 
Design Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best PracticesDesign Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best Practices
 
Next-gen Automation Framework
Next-gen Automation FrameworkNext-gen Automation Framework
Next-gen Automation Framework
 

Debugging MAD lecture june .pptx

  • 2. Debugging • In computer programming and software development, debugging is the process of finding and resolving bugs within computer programs, software, or systems.
  • 3. Debugging Flutter apps • variety of tools and features to help debug Flutter applications • DevTools, a suite of performance and profiling tools that run in a browser. • Android Studio/IntelliJ, and VS Code (enabled with the Flutter and Dart plugins) support a built-in source-level debugger with the ability to set breakpoints, step through code, and examine values. • Flutter inspector, a widget inspector available in DevTools, and also directly from Android Studio and IntelliJ (enabled with the Flutter plugin). The inspector allows you to examine a visual representation of the widget tree, inspect individual widgets and their property values, enable the performance overlay, and more
  • 4. DevTools • source-level debugger • widget inspector that displays a visual widget tree, and “widget select” mode where you select a widget in the app and it drills down to that widget in the tree • memory profiler • timeline view that supports tracing, and importing and exporting trace information • logging view
  • 5. Breakpoints, Dart analyzer and Logging • Breakpoints are one of the most important debugging techniques in your developer's toolbox. You set breakpoints wherever you want to pause debugger execution. • Flutter enabled IDE/editor, the Dart analyzer is already checking your code and looking for possible mistakes. • from the command line, test your code with flutter analyze. • You set logging up programmatically then view the output in the DevTools logging view, or in the console.
  • 6. Debugging application layers • Flutter was designed with a layered architecture that includes widget, rendering, and painting layers. • Flutter widget inspector provides a visual representation of the widget tree, but if you want a greater level of detail, or you want a verbose text-based dump of the widget, layer, or render trees • Widget tree • Render tree • Layer tree • Semantics tree • Scheduling
  • 7. Debugging application layers • To dump the state of the Widgets library, call debugDumpApp(). • If you are trying to debug a layout issue, then the Widgets layer’s tree might be insufficiently detailed. In that case, you can dump the rendering tree by calling debugDumpRenderTree(). • if you are trying to debug a compositing issue, you can use debugDumpLayerTree(). • You can also obtain a dump of the Semantics tree (the tree presented to the system accessibility APIs) using debugDumpSemanticsTree(). • To find out where your events happen relative to the frame’s begin/end, you can toggle the debugPrintBeginFrameBanner and the debugPrintEndFrameBanner booleans to print the beginning and end of the frames to the console.
  • 8. Debug flags: layout • You can also debug a layout problem visually, by setting debugPaintSizeEnabled to true. This is a boolean from the rendering library. • //add import to rendering library • import 'package:flutter/rendering.dart'; • void main() { • debugPaintSizeEnabled=true; • runApp(MyApp()); • }
  • 9. Debugging animations • Debug animations is to slow them down. You can do this using the Slow Animations button in DevTools’ Inspector view, which slows down the animation by 5x. • Set the timeDilation variable (from the scheduler library) to a number greater than 1.0, for instance, 50.0. • It’s best to only set this once on app startup.
  • 10. Debug flags: performance • Flutter provides a wide variety of debug flags and functions to help you debug your app at various points along the development cycle. • To use these features, you must compile in debug mode. • debugDumpRenderTree() • debugPaintLayerBordersEnabled • debugRepaintRainbowEnabled • debugPrintMarkNeedsLayoutStacks • debugPrintMarkNeedsPaintStacks
  • 11. Measuring app startup time • To gather detailed information about the time it takes for your Flutter app to start, you can run the flutter run command with the trace- startup and profile options. • The trace output is saved as a JSON file called start_up_info.json under the build directory of your Flutter project. • The output lists the elapsed time from app startup to these trace events • Time to enter the Flutter engine code. • Time to render the first frame of the app. • Time to initialize the Flutter framework. • Time to complete the Flutter framework initialization.
  • 12. Flutter's build modes • Flutter tooling supports three modes when compiling your app, and a headless mode for testing. • Use debug mode during development, when you want to use hot reload. • Use profile mode when you want to analyze performance. • Use release mode when you are ready to release your app.
  • 13. Debug Mode • Debug mode for mobile apps mean that: • Assertions are enabled. • Service extensions are enabled. • Compilation is optimized for fast development and run cycles (but not for execution speed, binary size, or deployment). • Debugging is enabled, and tools supporting source level debugging (such as DevTools) can connect to the process. • Debug mode for a web app means that: • The build is not minified and tree shaking has not been performed. • The app is compiled with the dartdevc compiler for easier debugging.
  • 14. Release • release mode for deploying the app, when you want maximum optimization and minimal footprint size. For mobile, release mode (which is not supported on the simulator or emulator), means that: • Assertions are disabled. • Debugging information is stripped out. • Debugging is disabled. • Compilation is optimized for fast startup, fast execution, and small package sizes. • Service extensions are disabled. • Release mode for a web app means that: • The build is minified and tree shaking has been performed. • The app is compiled with the dart2js compiler for best performance.
  • 15. Profile • profile mode, some debugging ability is maintained—enough to profile your app’s performance. Profile mode is disabled on the emulator and simulator, because their behavior is not representative of real performance. On mobile, profile mode is similar to release mode, with the following differences: • Some service extensions, such as the one that enables the performance overlay, are enabled. • Tracing is enabled, and tools supporting source-level debugging (such as DevTools) can connect to the process. • Profile mode for a web app means that: • The build is not minified but tree shaking has been performed. • The app is compiled with the dart2js compiler.
  • 16. Common Flutter errors • several frequently-encountered Flutter framework errors and gives suggestions on how to resolve them • A RenderFlex overflowed… • RenderFlex overflow is one of the most frequently encountered Flutter framework errors, and you probably have run into it already. • The error often occurs when a Column or Row has a child widget that is not constrained in its size. • Well, you need to make sure the Column won’t attempt to be wider than it can be. To achieve this, you need to constrain its width. One way to do it is to wrap the Column in an Expanded widget
  • 17. RenderBox was not laid out • While this error is pretty common, it’s often a side effect of a primary error occurring earlier in the rendering pipeline. • Usually, the issue is related to violation of box constraints, and it needs to be solved by providing more information to Flutter about how you’d like to constrain the widgets in question • The RenderBox was not laid out error is often caused by one of two other errors: • ‘Vertical viewport was given unbounded height’ • ‘An InputDecorator…cannot have an unbounded width’
  • 18. Vertical viewport was given unbounded height • This is another common layout error you could run into while creating a UI in your Flutter app. • The error is often caused when a ListView (or other kinds of scrollable widgets such as GridView) is placed inside a Column. • To fix this error, specify how tall the ListView should be. To make it as tall as the remaining space in the Column, wrap it using an Expanded widget (see the example below). Otherwise, specify an absolute height using a SizedBox widget or a relative height using a Flexible widget.
  • 19. Incorrect use of ParentData widget • This error is about missing an expected parent widget. • While Flutter’s widgets are generally flexible in how they can be composed together in a UI, a small subset of those widgets expect specific parent widgets. • The fix should be obvious once you know which parent widget is missing.
  • 20. Handling errors in Flutter • Flutter framework catches errors that occur during callbacks triggered by the framework itself, including errors encountered during the build, layout, and paint phases. • Errors that don’t occur within Flutter’s callbacks can’t be caught by the framework, but you can handle them by setting up a Zone. • By default, a Zone only prints errors and does nothing else. • All errors caught by Flutter are routed to the FlutterError.onError handler. • By default, this calls FlutterError.dumpErrorToConsole, which, as you might guess, dumps the error to the device logs.
  • 21. Handling errors in Flutter (Cont…) • When running from an IDE, the inspector overrides this so that errors can also be routed to the IDE’s console, allowing you to inspect the objects mentioned in the message. • When an error occurs during the build phase, the ErrorWidget.builder callback is invoked to build the widget that is used instead of the one that failed. • By default, in debug mode this shows an error message in red, and in release mode this shows a gray background.
  • 22. Errors caught by Flutter • import 'dart:io'; • import 'package:flutter/foundation.dart'; • import 'package:flutter/material.dart'; • void main() { • FlutterError.onError = (FlutterErrorDetails details) { • FlutterError.dumpErrorToConsole(details); • if (kReleaseMode) • exit(1); • }; • runApp(MyApp()); • } • // rest of `flutter create` code... This handler can also be used to report errors to a logging service. To make your application quit immediately any time an error is caught by Flutter in release mode
  • 23. Define a custom error widget for build phase errors • class MyApp extends StatelessWidget { • ... • @override • Widget build(BuildContext context) { • return MaterialApp( • ... • builder: (BuildContext context, Widget widget) { • Widget error = Text('...rendering error...'); • if (widget is Scaffold || widget is Navigator) • error = Scaffold(body: Center(child: error)); • ErrorWidget.builder = (FlutterErrorDetails errorDetails) => error; • return widget; • }, • ); • } • } To define a customized error widget that displays whenever the builder fails to build a widget, use MaterialApp.builder.
  • 24. Errors not caught by Flutter • OutlinedButton( • child: Text('Click me!'), • onPressed: () async { • final channel = const MethodChannel('crashy-custom-channel'); • await channel.invokeMethod('blah'); • }, • ), Consider an onPressed callback that invokes an asynchronous function, such as MethodChannel.invokeMethod
  • 25. • If invokeMethod throws an error, it won’t be forwarded to FlutterError.onError. Instead, it’s forwarded to the Zone where runApp was run. • To catch such an error, use runZonedGuarded. • import 'dart:async'; • void main() { • runZonedGuarded(() { • runApp(MyApp()); • }, (Object error, StackTrace stack) { • myBackend.sendError(error, stack); • }); • } Errors not caught by Flutter (Cont..)
  • 26. • Note that if in your app you call WidgetsFlutterBinding.ensureInitialized() manually to perform some initialization before calling runApp (e.g. Firebase.initializeApp()), you must call WidgetsFlutterBinding.ensureInitialized() inside runZonedGuarded: • runZonedGuarded(() async { • WidgetsFlutterBinding.ensureInitialized(); • await Firebase.initializeApp(); • runApp(MyApp()); • } Errors not caught by Flutter (Cont..) Note: Error handling wouldn’t work if WidgetsFlutterBinding.ensureInitialized() was called from the outside
  • 27. Handling all types of errors • import 'dart:io'; • import 'package:flutter/foundation.dart'; • import 'package:flutter/material.dart'; • void main() { • runZonedGuarded(() async { • WidgetsFlutterBinding.ensureInitialized(); • await myErrorsHandler.initialize(); • FlutterError.onError = (FlutterErrorDetails details) { • FlutterError.dumpErrorToConsole(details); • myErrorsHandler.onError(details); • exit(1); • }; • runApp(MyApp()); • }, (Object error, StackTrace stack) { • myErrorsHandler.onError(error, stack); • exit(1); • }); • } • class MyApp extends StatelessWidget { • @override • Widget build(BuildContext context) { • return MaterialApp( • builder: (BuildContext context, Widget widget) { • Widget error = Text('...rendering error...'); • if (widget is Scaffold || widget is Navigator) • error = Scaffold(body: Center(child: error)); • ErrorWidget.builder = (FlutterErrorDetails errorDetails) => error; • return widget; • }, • ); • } • } you want to exit application on any exception and to display a custom error widget whenever a widget building fails