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