Exception 颤振捕捉所有未处理的异常

Exception 颤振捕捉所有未处理的异常,exception,flutter,dart,Exception,Flutter,Dart,我正在尝试捕获一个Flutter应用程序中所有未处理的异常,以便将其发送给崩溃报告程序。有。我遵循这些原则,在我的应用程序中添加了两位代码以捕获异常: 通过在runZoned中包装runApp捕捉省道错误: runZoned<Future<void>>( () async { runApp(MyApp()); }, onError: (dynamic error, StackTrace stackTrace) { print("===

我正在尝试捕获一个Flutter应用程序中所有未处理的异常,以便将其发送给崩溃报告程序。有。我遵循这些原则,在我的应用程序中添加了两位代码以捕获异常:

通过在
runZoned
中包装
runApp
捕捉省道错误:

runZoned<Future<void>>(
  () async {
    runApp(MyApp());
  },
  onError: (dynamic error, StackTrace stackTrace) {
    print("=================== CAUGHT DART ERROR");
    // Send report
  },
);
但是,当我在运行时通过从按钮引发异常来测试此功能时:

throw Exception("Just testing");
控制台中会出现异常:

════════ 用手势捕捉异常 ═══════════════════════════════════════════════════════════════ 处理手势时引发了以下_异常:异常: 只是在异常发生时进行测试 抛出时,这是堆栈:

。。。等

但是我看不到我的打印语句的迹象(捕捉到的省道错误或捕捉到的颤振错误),并且在这些行上设置断点似乎从来没有命中,所以我认为我的异常处理代码没有捕捉到它。我错过什么了吗

下面是一个最小的可复制示例(单击按钮,它会引发异常,但未按预期捕获):

导入'dart:async';
进口“包装:颤振/材料.省道”;
void main()=>
runZoned(
()异步{
runApp(MyApp());
},
onError:(动态错误,StackTrace StackTrace){
打印(“捕捉到的省道错误”);
//发送报告
//从未到达这里-为什么?
},
);
类MyApp扩展了StatefulWidget{
//此小部件是应用程序的根。
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
@凌驾
void initState(){
super.initState();
//这将捕获颤振框架报告的错误。
flatterError.onError=(flatterErrorDetails){
打印(“捕捉到颤振错误”);
//发送报告
//从未到达这里-为什么?
};
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
正文:安全区(
孩子:升起按钮(
子项:文本(“抛出异常”),
已按下:(){
抛出异常(“这是一个测试异常”);
},
),
),
),
);
}
}

好的,我知道怎么回事了。查看了一些相关的颤振问题:


看起来,在调试模式下,Flatter框架会捕获很多异常,打印到控制台(有时会在UI中以红色和黄色显示),但不会重新抛出,因此它们会被有效地吞没,您自己的代码也无法捕获它们。但是,当您以发布模式部署时,这不会发生。因此,当在发布模式下构建时,我的最小可复制示例确实捕获异常。

因此,“runZoned”和“flutt.onError”分别用于dart和flutt框架中的“错误”处理。但在代码中,您正在抛出一个“异常”。“run…”或“…Oner”不处理的。如果您想在控制台中看到“Just testing”,请修改throw语句,如下->throw“Just testing”;您将在控制台日志中看到它。

注意:使用runZonedGuarded更新了一个错误弃用警告的示例代码

@james Allen我认为所有未处理的错误都可以被全局捕获&它可以在控制台中处理或打印,而不管模式如何。在您的示例中,我认为您没有在设置
flatterError.onError
之前添加这一行
WidgetsFlutterBinding.ensureInitialized()
,因此它可以正常工作

为了处理颤振中的
未处理异常
,我们从这些安全包装中获得帮助,以捕获这些异常,如下所示

  • 区域(捕获所有未处理的
    异步错误
  • flatterError.onError(捕获所有
    未处理的flatter框架错误

区域: 区域不属于颤振框架,它来自dart本身。在dart文档中,它指出

区域保护您的应用程序不因未捕获的异常而退出 由异步代码抛出

参考链接:

因此,通过将我们的应用程序封装到Flatter应用程序的内部区域,有助于捕获其简单代码下面所有未处理的异步错误

例如:


错误。错误: 从官方的颤振记录来看

颤振框架捕获回调期间发生的错误 由框架本身触发,包括在构建、布局和 油漆

所有这些错误都被路由到flatterError.onError处理程序。通过 默认情况下,这将调用flatterError.dumpErrorToConsole

参考链接:

因此,通过使用
flatterError.onError
我们可以捕获所有与颤振框架相关的错误,下面是它的简单示例

例如:

在设置颤振框架的错误捕获帮助程序之前,不要忘记先添加此行
WidgetsFlutterBinding.ensureInitialized()

注意

  • Flatter red screen to death错误也将在FlatterError.onError catcher下捕获
  • 默认情况下,在生产环境中,在开发模式下,颤振红色屏幕将可见。根据颤振文档,该屏幕将与普通背景一样
  • “颤振至死”屏幕可根据我们的创意定制
  • Flitter不会杀死应用程序,即使这些助手无法处理异常
  • 另外一个好处是,pub.dev中也有一个名为的库,您可以在其中查找错误捕获
  • dart&FLART框架的这两个助手的结合,我们可以在全球范围内捕获所有未处理的错误,这些都是我在FLART中被分配到全局异常处理任务时从web文档中了解到的,如果有任何错误,请随时更正。

    您是否同意
    throw Exception("Just testing");
    
    import 'dart:async';
    import 'package:flutter/material.dart';
    
    void main() =>
      runZoned<Future<void>>(
        () async {
          runApp(MyApp());
        },
        onError: (dynamic error, StackTrace stackTrace) {
          print("=================== CAUGHT DART ERROR");
          // Send report
          // NEVER REACHES HERE - WHY?
        },
      );
    
    class MyApp extends StatefulWidget {
      // This widget is the root of your application.
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
    
      @override
      void initState() {
        super.initState();
    
        // This captures errors reported by the FLUTTER framework.
        FlutterError.onError = (FlutterErrorDetails details) {
          print("=================== CAUGHT FLUTTER ERROR");
          // Send report
          // NEVER REACHES HERE - WHY?
        };
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: SafeArea(
              child: RaisedButton(
                child: Text("Throw exception"),
                onPressed: () {
                  throw Exception("This is a test exception");
                },
              ),
            ),
          ),
        );
      }
    }
    
    void main() {
      runZonedGuarded(() async {
        runApp(MyApp()); // starting point of app
       },(error, stackTrace) {
          print("Error FROM OUT_SIDE FRAMEWORK ");
          print("--------------------------------");
          print("Error :  $error");
          print("StackTrace :  $stackTrace");
      });
     }
    
    void main() {
        WidgetsFlutterBinding.ensureInitialized(); //imp line need to be added first
        FlutterError.onError = (FlutterErrorDetails details) {
        //this line prints the default flutter gesture caught exception in console
        //FlutterError.dumpErrorToConsole(details);
        print("Error From INSIDE FRAME_WORK");
        print("----------------------");
        print("Error :  ${details.exception}");
        print("StackTrace :  ${details.stack}");
        };
        runApp(MyApp()); // starting point of app
     }