最近自己在写一个独立APP, 用flutter开发, 不定期发布一些踩坑记录, 这篇文章是用来结合catcher, 专门用来处理全局错误的一个flutter插件.
使用很简单, 文档写的也很详细, 地址在:
https://pub.flutter-io.cn/packages/catcher
dependencies:
catcher: ^0.3.0
使用需要引用
import 'package:catcher/catcher_plugin.dart';
不过一般只需要在main.dart里进行配置就行了
CatcherOptions debugOptions = CatcherOptions(DialogReportMode(), [
PostHandler(HttpRequestType.post,
Uri.parse(Api.ERROR_REPORT_URL),
printLogs: true)
]);
CatcherOptions releaseOptions = CatcherOptions(PageReportMode(), [
ConsoleHandler(),
PostHandler(HttpRequestType.post,
Uri.parse(Api.ERROR_REPORT_URL))
]);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
Catcher(ProviderNode(child: MyApp(), providers: providers), debugConfig: debugOptions, releaseConfig: releaseOptions);
});
因为我配置了Provider 所以这么写, 如果没使用的直接用Cather(runApp(MyApp))就行
CatcherOptions 可以配置多个, 对应不同时期使用的策略
PostHandler是我自己重新写的提交到服务器的策略,
对MyAPp里的build进行配置, 可以构建公共的错误页面
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
final router = Router();
Routes.configureRoutes(router);
Application.router = router;
return MaterialApp(
title: 'xxx',
debugShowCheckedModeBanner: false,
navigatorKey: Catcher.navigatorKey,
builder: (BuildContext context, Widget widget) {
Catcher.addDefaultErrorWidget(
showStacktrace: false,
customTitle: "十分抱歉, 程序出现错误",
customDescription: "希望你能将这个错误报告给我们, 以此来帮助我们更好的改进, 你的帮助是我们前进的动力.");
return widget;
},
onGenerateRoute: Application.router.generator,
theme: ThemeData(
primaryColor: Colors.lightBlueAccent,
),
home: SplashPage());
}
}
import 'package:catcher/catcher_plugin.dart';
import 'package:catcher/utils/catcher_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
class PostHandler extends ReportHandler {
final Dio _dio = Dio();
final Logger _logger = Logger("HttpHandler");
final HttpRequestType requestType;
final Uri endpointUri;
Map<String, dynamic> headers = {};
final int requestTimeout;
final int responseTimeout;
final bool printLogs;
PostHandler(this.requestType, this.endpointUri,
{this.requestTimeout = 5000,
this.responseTimeout = 5000,
this.printLogs = false}) {
assert(this.requestType != null, "Request type can't be null");
assert(this.endpointUri != null, "Endpoint uri can't be null");
}
@override
Future<bool> handle(Report error) async {
if (!(await CatcherUtils.isInternetConnectionAvailable())) {
_printLog("No internet connection available");
return false;
}
if (requestType == HttpRequestType.post) {
return _sendPost(error);
}
return true;
}
_printLog(String log) {
if (printLogs) {
_logger.info(log);
}
}
//发送请求上传错误信息
Future<bool> _sendPost(Report error) async {
//获取应用信息
try {
var json = error.toJson();
Options options = Options(
sendTimeout: requestTimeout,
receiveTimeout: responseTimeout,
headers: headers);
Response response = await _dio
.post(endpointUri.toString(), data: json, options: options);
_printLog(
"HttpHandler response status: {response.data}");
return SynchronousFuture(true);
} catch (error, stackTrace) {
return SynchronousFuture(false);
}
}
}