Files
jiu/client/lib/main.dart
T
wangjia 2dbc89b902 feat: 错误自动上报机制
- 后端:error_reports 表 + POST /api/v1/public/errors + GET /api/v1/admin/errors
- Flutter:ErrorReporter 单例,60s 去重,fire-and-forget,不影响用户
- main.dart:FlutterError 和 Zone 错误自动上报
- 打印异常:catch 块加 reportError,Windows 打印问题可自动采集堆栈

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 21:08:03 +08:00

82 lines
2.6 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
import 'core/auth/auth_state.dart';
import 'core/errors/error_reporter.dart';
import 'core/router/app_router.dart';
import 'core/theme/app_theme.dart';
import 'providers/connectivity_provider.dart';
void main() {
usePathUrlStrategy();
FlutterError.onError = (details) {
FlutterError.presentError(details);
debugPrint('═══ FlutterError ════════════════════════════');
debugPrint(details.exceptionAsString());
debugPrint(details.stack.toString());
ErrorReporter.instance.report(
errorType: ErrorType.flutterError,
errorMsg: details.exceptionAsString(),
stackTrace: details.stack,
);
};
runZonedGuarded(
() => runApp(const ProviderScope(child: JiuApp())),
(error, stack) {
debugPrint('═══ Zone Error ═══════════════════════════════');
debugPrint(error.toString());
debugPrint(stack.toString());
ErrorReporter.instance.report(
errorType: ErrorType.zoneError,
errorMsg: error.toString(),
stackTrace: stack,
);
},
);
}
class JiuApp extends ConsumerStatefulWidget {
const JiuApp({super.key});
@override
ConsumerState<JiuApp> createState() => _JiuAppState();
}
class _JiuAppState extends ConsumerState<JiuApp> {
@override
void initState() {
super.initState();
// 异步初始化:恢复 auth + 连通性检测
// 路由 redirect 在 initialized=false 时返回 null(不重定向),
// 初始化完成后 authState 变化触发 router refreshredirect 重新执行
WidgetsBinding.instance.addPostFrameCallback((_) async {
await ref.read(authStateProvider.notifier).restore();
await ref.read(connectivityProvider.notifier).forceCheck();
});
}
@override
Widget build(BuildContext context) {
final router = ref.watch(appRouterProvider);
return MaterialApp.router(
title: '岩美',
theme: AppTheme.light(),
routerConfig: router,
debugShowCheckedModeBanner: false,
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('zh', 'CN'),
Locale('en', 'US'),
],
locale: const Locale('zh', 'CN'),
);
}
}