React Native的Sentry错误上报

Sentry 的 RN 埋点分为两种,React Native 分为两种:

两者的区别是 react-native-sentry 需要 native 的协助,需要安装对应的客户端依赖,能够更好的捕获RN导致的崩溃错误。raven.js 是纯 js 的上报,纯 js 的上报只能说够用,不能定位到源码的情况,但是从接口情况,以及页面breadcrumb,也能够大概定位到bug的位置。

对比 react-native-sentry 和 raven.js

react-native-sentry 的缺点

  • 打包会涉及 source-map,体积会变大,不符合热更新的需求。
  • 判断机型方面,ios 和 android 情况不太一样。安卓功能受限,价值不大。

采用 raven.js 有一定道理,够用,把 crash 的情况收集交给 native。如今市面上基本上都是混合 app,并不是纯 RN 应用。如果错误的收集让 App 的体积变大,显然有点不合适。

如果是纯RN应用,expo则会自带react-native-sentry。

raven.js 的缺点

官方已经废弃,考虑到sentry-javascript源码有AsyncStorage,而且该 api 会在 RN 后续版本0.59中废弃。所以如果日后 RN 版本升级后,考虑错误上报的公共代码修改是必要的。建议如果60以后的RN版本建议更换成为sentry-react-native

错误类型

错误的类型分为两种:

  • 渲染报错
  • JS 端报错

渲染报错是由 react 机制内控制,错误的信息会触发生命周期getDerivedStateFromError, 所以在周期回收错误信息即可Raven.captureException(error),参考React Error Boundaries

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    Raven.captureException(error);
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
     // 尝试过,但是并没有在RN59触发
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

JS 端报错是在 react 机制外控制,需要调用Raven的 react-native plugin。原理是通过 react native 的官方 apiErrorUtils捕获 JS 端的“红屏”错误,详情请参考sentry-javascript。使用方法如下:

var Raven = require('raven-js');
Raven.addPlugin(require('raven-js/plugins/react-native'));

做了这两部操作基本完成了RN的代码逻辑层的错误上报。

相关信息

在项目初始化的时候,Raven.setUserContext(params)会自动将用户 App 相关信息回收,有利于线上问题的判断,大家可以结合自己App的用户数据进行处理。 而Raven.captureBreadcrumb是关键的错误信息点。关键错误信息点的流程有助于错误流程的区分。

推荐阅读更多精彩内容