You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 22:39:19