Jam*_*len 29 exception dart flutter
我试图在 Flutter 应用程序中捕获所有未处理的异常,以便将其发送给崩溃报告者。Flutter 文档中有关于如何执行此操作的说明。我遵循了这些,并在我的应用程序中添加了两段代码以捕获异常:
通过包装runApp来捕捉 Dart 错误runZoned:
runZoned<Future<void>>(
() async {
runApp(MyApp());
},
onError: (dynamic error, StackTrace stackTrace) {
print("=================== CAUGHT DART ERROR");
// Send report
},
);
Run Code Online (Sandbox Code Playgroud)
通过设置捕捉颤振错误FlutterError.onError:
FlutterError.onError = (FlutterErrorDetails details) {
print("=================== CAUGHT FLUTTER ERROR");
// Send report
};
Run Code Online (Sandbox Code Playgroud)
但是,当我在运行时通过从按钮抛出异常进行测试时:
throw Exception("Just testing");
Run Code Online (Sandbox Code Playgroud)
控制台中出现异常:
????????? 异常捕获手势???????????????????????????????????????????????? ????????????????????? 处理手势时抛出了以下 _Exception: Exception: Just testing 当抛出异常时,这是堆栈:
... 等等
但是我看不到我的打印语句的迹象(CAUGHT DART ERROR 或 CAUGHT FLUTTER ERROR),并且在这些行上设置断点似乎永远不会命中,所以我认为我的异常处理代码没有捕捉到它。我错过了什么吗?
这是一个最小的可重现示例(单击按钮,该按钮会引发异常,但未按预期捕获):
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");
},
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
Jam*_*len 37
好吧,我想通了是怎么回事。查看了一些相关的 Flutter 问题:
看起来在调试模式下,flutter 框架捕获了很多异常,打印到控制台(有时在 UI 本身中以红色和黄色显示),但不会重新抛出 - 所以它们被有效地吞下,并且有您自己的代码无法捕获它们。但是,当您在发布模式下部署时,这不会发生。因此,我的最小可重现示例在以发布模式构建时确实会捕获异常。
Sar*_*aja 16
注意:使用 runZonedGuarded 更新了 onError deprecated 警告的示例代码
嗨@james Allen我认为所有未处理的错误都可以全局捕获,并且无论模式如何,它都可以在控制台中处理或打印。在您的示例中,我认为您WidgetsFlutterBinding.ensureInitialized()在设置之前错过了添加此行,flutterError.onError因此它可以像您一样工作,但除外。
为了处理unhandled exceptions颤振,我们从这些安全包装中获得帮助以捕获这些异常,如下所列
unhandled-asynchronous-errors)unhandled-flutter-framework-errors)zone 不属于 flutter 框架,它来自 dart 本身。在 dart 文档中,它指出..
区域保护您的应用程序不会因异步代码引发的未捕获异常而退出
参考链接:https : //dart.dev/articles/archive/zones#handling-asynchronous-errors
因此,通过将我们的应用程序包装在 zone 内到我们的 flutter 应用程序,有助于捕获其简单代码下方的所有未处理的异步错误。
示例:
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");
});
}
Run Code Online (Sandbox Code Playgroud)
来自官方颤振文档,它说,
Flutter 框架会捕获在框架本身触发的回调期间发生的错误,包括在构建、布局和绘制期间。
所有这些错误都被路由到 FlutterError.onError 处理程序。默认情况下,这会调用 FlutterError.dumpErrorToConsole,
参考链接:https : //flutter.dev/docs/testing/errors
所以通过使用flutterError.onError我们可以捕获所有与颤振框架相关的错误,下面是它的简单示例..
例子:
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
}
Run Code Online (Sandbox Code Playgroud)
WidgetsFlutterBinding.ensureInitialized()在设置 flutter 框架的错误捕获助手之前,不要忘记先添加这一行。
注意:
结合 dart 和 flutter 框架中的这两个助手,我们可以全局捕获所有未处理的错误,这些都是我在 flutter 中被分配执行全局异常处理任务时从 Web 文档中了解到的,如果有任何错误,请随时纠正我。
Duy*_*ran 10
确保您像这样使用WidgetsFlutterBinding.ensureInitialized()
runZonedGuarded(() {
WidgetsFlutterBinding.ensureInitialized(); //<= the key is here
FlutterError.onError = (FlutterErrorDetails errorDetails) {
Utilities.log("Will log here ${errorDetails.exception.toString()}");
};
runApp(app);
}, (error, stackTrace) {
Utilities.log("Others catching ${error.toString()}");
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17900 次 |
| 最近记录: |