Flutter开发 - flutter异常上报方案,sentry的用法

1,739 阅读2分钟

在原生App中,我们用来监听异常和崩溃的工具有很多,主流的有Bugly,友盟等等。而在flutter中,异常的监听就没那么容易了,好在官方提供了一个插件供我们使用,这就是sentry,关于sentry的用法,官方没有解释太详细,网上资料也不多,但也能找到,不过有些写的比较简单,没有详细解释原因,所以在使用过程中难免要走不少的弯路。

今天博主就把sentry的使用方法略加详细的介绍一下,还有一些扩展的用法;

1.首先sentry的使用需要先搭建自己的私服,这个可能需要后端的小伙伴来帮忙部署;

2.搭建成功后可以在平台上创建对应项目,拿到一个DSN,这个DSN包含了你要上传的地址信息;

3.sentry平台不仅仅flutter能使用,前端也是可以使用的哦;

本文只针对flutter做介绍。sentry一般要写在main.dart的入口函数中,看下代码:

const dsn='xxxxxxx';
final SentryClient _sentry = new SentryClient(
  dsn: dsn,
);

Future<Null> main() async {
  ///用于捕获framework在某一时刻的错误
  FlutterError.onError = (FlutterErrorDetails details) async {
    if (isInDebugMode) {
      ///debug模式下,将错误转到控制台输出,可以通过detail的bool值控制
      FlutterError.dumpErrorToConsole(details);
    } else {
      ///捕获的异步错误,转到应用的root zone处理,就是main方法中runZoned的异常处理中
      Zone.current.handleUncaughtError(details.exception, details.stack);
    }
  };
  ///开一个长开端口监听异常
  Isolate.current.addSentryErrorListener(_sentry);
  ///在应用的root zone中捕获异常,可以认为是,可捕获整个应用运行周期内的所有异常
  runZoned<Future<Null>>(() async {
        runApp(MyApp());
  }, onError: (error, stackTrace) async {
    await _reportError(error, stackTrace);
  });
}

Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
//用于判断是否是debug模式
  if (isInDebugMode) {
    print(stackTrace);
    return;
  }
	final SentryResponse response = await _sentry.capture(
      event: Event(
          exception: error,
          stackTrace: stackTrace,
      ),
    );
    // 上报结果处理
    if (response.isSuccessful) {
      print('Success! Event ID: ${response.eventId}');
    } else {
      print('Failed to report to Sentry.io: ${response.error}');
    }
}
//获取运行的模式
bool get isInDebugMode {
  bool inDebugMode = false;
  assert(inDebugMode = true);
  return inDebugMode;
}

// Candidate API for the SDK
extension IsolateExtensions on Isolate {
  void addSentryErrorListener(SentryClient sentry) {
    ///打开一个用于接收消息的长期端口,然后来监听异常,关于Isolate,是有自己的内存和单线程控制的运行实体,isolate之间的内存在逻辑上是隔离的,相当于监听的端口是隔离的,不会受其他影响而打断
    final receivePort = RawReceivePort(
          (dynamic values) async {
        await sentry.captureIsolateError(values);
      },
    );

    Isolate.current.addErrorListener(receivePort.sendPort);
  }
}

// Candidate API for the SDK
extension SentryExtensions on SentryClient {
  Future<void> captureIsolateError(dynamic error) {
    print('Capture from IsolateError $error');
    ///这里是一个堆栈跟踪的字符串转化
    if (error is List<dynamic> && error.length != 2) {
      dynamic stackTrace = error[1];
      if (stackTrace != null) {
        stackTrace = StackTrace.fromString(stackTrace as String);
      }
      return captureException(exception: error[0], stackTrace: stackTrace);
    } else {
      return Future.value();
    }
  }
}

注释已经写了,有啥不明白的可以提问,这篇博客讲解了sentry的基本使用,关于sentry的扩展:
1.增加版本号的上传;
2.在异常上报的过程中对app进行截图,然后上传到sentry;

以上两个扩展将在后续博客中发布,欢迎持续关注。