如何修复Flutter中的Sentry Zone mismatch错误?
Zone不匹配问题排查与解决
框架/SDK版本
Flutter: 3.10.4 Dart: 3.0.3
问题代码
Future<void> main() async { //debugPaintSizeEnabled = true; //BindingBase.debugZoneErrorsAreFatal = true; WidgetsFlutterBinding.ensureInitialized(); EasyLocalization.ensureInitialized() .then((value) => Fimber.plantTree(DebugTree())) .then((value) => SentryFlutter.init( (options) { options.dsn = '***'; // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. // We recommend adjusting this value in production. options.tracesSampleRate = 1.0; //options.attachScreenshot = true; }, appRunner: () => runApp( EasyLocalization( supportedLocales: const [Locale('en', 'US'), Locale('de', 'DE')], path: '../assets/translations/', fallbackLocale: const Locale('en', 'US'), assetLoader: const CodegenLoader(), child: MyApp(), ), ), )); }
报错信息
Exception caught by Flutter framework ===================================================== The following assertion was thrown during runApp: Zone mismatch. The Flutter bindings were initialized in a different zone than is now being used. This will likely cause confusion and bugs as any zone-specific configuration will inconsistently use the configuration of the original binding initialization zone or this zone based on hard-to-predict factors such as which zone was active when a particular callback was set. It is important to use the same zone when calling `ensureInitialized` on the binding as when calling `runApp` later. To make this warning fatal, set BindingBase.debugZoneErrorsAreFatal to true before the bindings are initialized (i.e. as the first statement in `void main() { }`). When the exception was thrown, this was the stack: dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 942:28 get current packages/flutter/src/foundation/binding.dart 497:29 <fn> packages/flutter/src/foundation/binding.dart 501:14 debugCheckZone packages/flutter/src/widgets/binding.dart 1080:17 runApp packages/ens_price_calculator/main.dart 52:30 <fn> packages/sentry/src/sentry.dart 136:26 <fn> dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50 <fn> dart-sdk/lib/async/zone.dart 1407:47 _rootRunUnary dart-sdk/lib/async/zone.dart 1308:19 runUnary dart-sdk/lib/async/future_impl.dart 147:18 handleValue dart-sdk/lib/async/future_impl.dart 784:44 handleValueCallback dart-sdk/lib/async/future_impl.dart 813:13 _propagateToListeners dart-sdk/lib/async/future_impl.dart 584:5 [_completeWithValue] dart-sdk/lib/async/future_impl.dart 657:7 <fn> dart-sdk/lib/async/zone.dart 1399:13 _rootRun dart-sdk/lib/async/zone.dart 1301:19 run dart-sdk/lib/async/zone.dart 1209:7 runGuarded dart-sdk/lib/async/zone.dart 1249:23 callback dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 177:15 <fn> =================================================================================================
解决方案
错误核心原因:WidgetsFlutterBinding.ensureInitialized()在默认Zone执行,但runApp被Sentry初始化逻辑包装到了新的Zone中,导致上下文Zone不匹配。
方案1:将绑定初始化移到Sentry的Zone内执行
调整代码顺序,让Sentry先创建Zone,再初始化Flutter绑定,确保整个流程在同一个Zone中:
Future<void> main() async { //debugPaintSizeEnabled = true; //BindingBase.debugZoneErrorsAreFatal = true; await EasyLocalization.ensureInitialized(); Fimber.plantTree(DebugTree()); await SentryFlutter.init( (options) { options.dsn = '***'; options.tracesSampleRate = 1.0; //options.attachScreenshot = true; }, appRunner: () { WidgetsFlutterBinding.ensureInitialized(); runApp( EasyLocalization( supportedLocales: const [Locale('en', 'US'), Locale('de', 'DE')], path: '../assets/translations/', fallbackLocale: const Locale('en', 'US'), assetLoader: const CodegenLoader(), child: MyApp(), ), ); }, ); }
方案2:用async/await替代链式then调用
链式then会导致Zone上下文切换,改用async/await保持上下文一致性:
Future<void> main() async { //debugPaintSizeEnabled = true; //BindingBase.debugZoneErrorsAreFatal = true; WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); Fimber.plantTree(DebugTree()); await SentryFlutter.init( (options) { options.dsn = '***'; options.tracesSampleRate = 1.0; //options.attachScreenshot = true; }, ); runApp( EasyLocalization( supportedLocales: const [Locale('en', 'US'), Locale('de', 'DE')], path: '../assets/translations/', fallbackLocale: const Locale('en', 'US'), assetLoader: const CodegenLoader(), child: MyApp(), ), ); }
注意:方案2需要确认当前Sentry版本不需要强制在其Zone内运行runApp,如果仍有问题,优先选择方案1。
内容的提问来源于stack exchange,提问作者Void
相关产品推荐
相关产品推荐

