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
是关键的错误信息点。关键错误信息点的流程有助于错误流程的区分。