当前位置:网站首页>Exception handling errorwidget in fluent page

Exception handling errorwidget in fluent page

2020-12-03 08:27:32 osc_ tmxtbi57

Flutter Exception handling in

Dart It's a single process mechanism , So problems in this process will only affect the current process , In the event loop , When an exception occurs in a task and is not caught , The program doesn't exit , And the direct result is The subsequent code of the current task will not be executed , In other words, the exception in one task will not affect the execution of other tasks .

Flutter abnormal

Flutter Anomalies are ,Flutter In the program Dart Unexpected error event when code is running . We can Java Allied try-catch Mechanisms to capture it . but And Java The difference is ,Dart The program doesn't force us to handle exceptions .

This is because ,Dart Use the event loop mechanism to run tasks , So the running state of each task is independent of each other . in other words , Even if an exception occurs to a task, we don't catch it ,Dart The program doesn't exit either , It will only cause the subsequent code of the current task not to be executed , Users can still use other features .

Dart abnormal , According to the source, it can be subdivided into App Exceptions and Framework abnormal .Flutter Different capture methods are provided for these two exceptions , Let's take a look at it together .

App How to catch exceptions

App abnormal , It's an exception to the application code , It is usually caused by exceptions thrown by other modules of the application layer that are not handled . According to the execution timing of the exception code ,App There are two types of exceptions , That is, synchronous exception and asynchronous exception : Synchronization exceptions can be passed through try-catch Mechanism capture , Asynchronous exceptions need to use Future Provided catchError Statements capture .

These two ways of exception capture , As shown in the following code :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//  Use  try-catch  Catch synchronization exception 
try {
  throw StateError('This is a Dart exception.');
}
catch(e) {
  print(e);
}
 
//  Use  catchError  Catch asynchronous exception 
Future.delayed(Duration(seconds: 1))
    .then((e) => throw StateError('This is a Dart exception in Future.'))
    .catchError((e)=>print(e));
    
//  Be careful , The following code cannot catch asynchronous exceptions 
try {
  Future.delayed(Duration(seconds: 1))
      .then((e) => throw StateError('This is a Dart exception in Future.'))
}
catch(e) {
  print("This line will never be executed. ");
}

It should be noted that , You can't mix the two ways . You can see , In the code above , We can't use try-catch To catch an exception thrown by an asynchronous call .

synchronous try-catch And asynchronous catchError, Provides us with the ability to capture specific exceptions directly , And if we want to centrally manage all the exceptions in the code ,Flutter Also provided Zone.runZoned Method .

We can assign a code execution object a Zone, stay Dart in ,Zone Represents the scope of the environment in which a code is executed , The concept is similar to sandbox , Different sandboxes are isolated from each other . If we want to look at code execution exceptions in sandbox , Sandbox provides onError Callback function , Intercept uncapped exceptions in code execution objects .

In the following code , We put statements that might throw exceptions in Zone in . You can see , Before use try-catch and catchError Under the circumstances , Whether it's a synchronous exception or an asynchronous exception , Both can pass Zone Directly capture :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
runZoned(() {
  //  Synchronization exception 
  throw StateError('This is a Dart exception.');
}, onError: (dynamic e, StackTrace stack) {
  print('Sync error caught by zone');
});
 
runZoned(() {
  //  Asynchronous exception 
  Future.delayed(Duration(seconds: 1))
      .then((e) => throw StateError('This is a Dart exception in Future.'));
}, onError: (dynamic e, StackTrace stack) {
  print('Async error aught by zone');
});

therefore , If we want to concentrate on capturing Flutter Unhandled exception in application , You can put main Function runApp Statements are also placed in Zone in . In this way, when an exception is detected in the code , We can use the exception context information we get , It has been unified :

1
2
3
4
5
runZoned<Future<Null>>(() async {
  runApp(MyApp());
}, onError: (error, stackTrace) async {
 //Do sth for error
});

below , Let's see Framework How to catch exceptions .

Flutter Framework exception capture

Flutter Framework for us in many key methods for exception capture . Here is an example , When our layout is out of bounds or out of specification ,Flutter An error interface will pop up automatically , This is because Flutter It's already in execution build Method is added with exception capture , The final source code is as follows :

1
2
3
4
5
6
7
8
9
10
11
12
@override
void performRebuild() {
 ...
  try {
    // perform build Method   
    built = build();
  } catch (e, stack) {
    //  If there is an exception, an error prompt will pop up   
    built = ErrorWidget.builder(_debugReportException('building $this', e, stack));
  } 
  ...
}

You can see , When an exception occurs ,Flutter The default processing method is to play a ErrorWidget , But what should we do if we want to catch the exception ourselves and report it to the alarm platform ? We enter  _debugReportException()  Methods take a look at :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FlutterErrorDetails _debugReportException(
  String context,
  dynamic exception,
  StackTrace stack, {
  InformationCollector informationCollector
}) {
  // Build error detail object   
  final FlutterErrorDetails details = FlutterErrorDetails(
    exception: exception,
    stack: stack,
    library: 'widgets library',
    context: context,
    informationCollector: informationCollector,
  );
  // Report error  
  FlutterError.reportError(details);
  return details;
}

We found that , The mistake is through  FlutterError.reportError  Method reported , Continue tracking :

1
2
3
4
5
static void reportError(FlutterErrorDetails details) {
  ...
  if (onError != null)
    onError(details); // Called onError Callback 
}

We found that  onError  yes  FlutterError  A static property of , It has a default processing method
dumpErrorToConsole, It's clear here , If we want to report exceptions ourselves , It only needs Provides a custom error handling callback that will do , Such as :

1
2
3
4
5
6
void main() {
  FlutterError.onError = (FlutterErrorDetails details) {
    reportError(details);
  };
 ...
}

Here we use Zone Provided handleUncaughtError sentence , take Flutter Exceptions of the framework are uniformly forwarded to the current Zone in , In this way, we can use Zone To handle all exceptions in the application :

1
2
3
4
5
6
7
8
9
10
FlutterError.onError = (FlutterErrorDetails details) async {
  //  Forward exception to  Zone  in 
  Zone.current.handleUncaughtError(details.exception, details.stack);
};
 
runZoned<Future<Null>>(() async {
  runApp(MyApp());
}, onError: (error, stackTrace) async {
 // Handle all exception information 
});

In the same way, we can use ErrorWidget.builder From defining the error interface

1
2
3
4
5
6
7
8
9
10
11
12
13
ErrorWidget.builder = (FlutterErrorDetails flutterErrorDetails) {
  return Scaffold(
      body: Center(
    child: Column(children: [
      Icon(
        Icons.error,
        color: Colors.red,
        size: 100,
      ),
      Text(flutterErrorDetails.exceptionAsString())
    ]),
  ));
};

Wrong pictures and wrong text displayed in an office

exception handling

In the error screen, we can use Zone The error callback in handles all caught exceptions , Of course , We can consider putting Error file stored in file , Upload to the server or to the error analysis platform .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import 'dart:async';

import 'package:flutter/material.dart';

main() {
  FlutterError.onError = (FlutterErrorDetails details) async {
    //  Forward to  Zone  Error callback of 
    Zone.current.handleUncaughtError(details.exception, details.stack);
  };

ErrorWidget.builder = (FlutterErrorDetails flutterErrorDetails) {
    return Scaffold(
        body: Container(
      padding: EdgeInsets.only(left: 20, right: 20),
      child: Column(children: [
        Icon(
          Icons.error,
          color: Colors.red,
          size: 100,
        ),
        Text(
          flutterErrorDetails.exceptionAsString(),
          style: TextStyle(color: Colors.blue, fontSize: 14),
          textAlign: TextAlign.start,
        )
      ]),
    ));
  };

  runZoned<Future<Null>>(() async {
    runApp(new MaterialApp(
      home: HomePage(),
    ));
  }, onError: (error, stackTrace) async {
    print(error.toString());
  });
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ExceptionTitle"),
      ),
      body: Center(
        child: RaisedButton(
          child: Text(" abnormal "),
          onPressed: () {
            throw new Exception(" Custom exception ");
          },
        ),
      ),
    );
  }
}

We define an interface with a button in the middle , Clicking on the button will throw a custom exception , stay main In the method, we will FlutterError Call back the error in to Zone in , And print the captured exception information to the console .

image-20200703173746128

Click the exception button , Watch the console output

image-20200703173849117

Again, we have customized the error interface , When there is an error in the interface construction, our custom error interface will be displayed

image-20200703174632008

Summary

  • App abnormal , We can put the code execution block into Zone in , adopt onError Callback for unified processing
  • Framework abnormal , We can use FlutterError.onError Callback to intercept
  • By way of FlutterError.onError Forwarding to Zone Exception handling can be unified in
  • ErrorWidget.builder You can customize the error interface

版权声明
本文为[osc_ tmxtbi57]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/202012030826065735.html

随机推荐