Flutter向Crashlytics上报未捕获框架错误时如何携带自定义参数
Flutter Crashlytics 未捕获错误附带自定义参数实现方案
直接替换原有直接赋值FlutterError.onError的写法,按以下两步配置即可:
- 第一步:全局维护当前页面上下文
新增路由观察者,实时记录当前激活的页面名称、页面传参,注册到MaterialApp的路由监听中:
// 全局路由状态观察者 class RouteStateObserver extends NavigatorObserver { static String? currentPageName; static Map? currentPageArgs; @override void didPush(Route route, Route? previousRoute) { super.didPush(route, previousRoute); currentPageName = route.settings.name; currentPageArgs = route.settings.arguments as Map?; } @override void didPop(Route route, Route? previousRoute) { super.didPop(route, previousRoute); currentPageName = previousRoute?.settings.name; currentPageArgs = previousRoute?.settings.arguments as Map?; } @override void didReplace({Route? newRoute, Route? oldRoute}) { super.didReplace(newRoute: newRoute, oldRoute: oldRoute); currentPageName = newRoute?.settings.name; currentPageArgs = newRoute?.settings.arguments as Map?; } } // 注册到MaterialApp MaterialApp( navigatorObservers: [RouteStateObserver()], // 其余应用配置 )
- 第二步:重写错误上报逻辑,上报前注入自定义参数
不要直接将recordFlutterFatalError赋值给FlutterError.onError,自定义错误处理回调,先设置自定义键值对再执行上报,同时覆盖异步未捕获错误的上报逻辑:
// 覆盖框架同步未捕获错误 FlutterError.onError = (FlutterErrorDetails details) async { // 注入当前页面信息 if (RouteStateObserver.currentPageName != null) { await FirebaseCrashlytics.instance.setCustomKey("trigger_page", RouteStateObserver.currentPageName!); } if (RouteStateObserver.currentPageArgs != null) { // Crashlytics自定义键仅支持基础类型,复杂参数转字符串存储 await FirebaseCrashlytics.instance.setCustomKey("page_params", RouteStateObserver.currentPageArgs.toString()); } // 执行原有致命错误上报 FirebaseCrashlytics.instance.recordFlutterFatalError(details); }; // 覆盖异步未捕获错误,App启动时用runZonedGuarded包裹runApp runZonedGuarded(() { runApp(const MyApp()); }, (Object error, StackTrace stack) async { // 同样先注入页面上下文 if (RouteStateObserver.currentPageName != null) { await FirebaseCrashlytics.instance.setCustomKey("trigger_page", RouteStateObserver.currentPageName!); } if (RouteStateObserver.currentPageArgs != null) { await FirebaseCrashlytics.instance.setCustomKey("page_params", RouteStateObserver.currentPageArgs.toString()); } // 上报异步错误 await FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); });
补充说明
setCustomKey设置的键值对会随后续所有上报携带,每次上报前设置的新值会覆盖旧值,无需手动清理。- 针对特定场景需要追加关联信息的(比如示例中的图片加载错误),可以在对应逻辑执行前提前设置自定义键,比如加载网络图片前先将图片URL存入自定义键,报错时就能直接定位到出问题的资源地址。
- 全局需要统一携带的信息(比如用户ID、设备标识、应用版本)也可以在这个上报拦截逻辑中统一注入,不需要每个业务场景单独设置。
内容的提问来源于stack exchange,提问作者Alex Aung
相关产品推荐
相关产品推荐

