JS原生错误
除了try catch中捕获住的错误,我们还需要上报没有被捕获住的错误——通过error事件和unhandledrejection事件去监听。
错误报警三类监控;首先是js、最后是react、vue的项目
js error事件
error事件是用来监听DOM操作错误DOMException和JS错误告警的,具体来说,JS错误分为下面8类:
- InternalError: 内部错误,比如如递归爆栈;
- RangeError: 范围错误,比如new Array(-1);
- EvalError: 使用eval()时错误;
- ReferenceError: 引用错误,比如使用未定义变量;
- SyntaxError: 语法错误,比如var a = ;
- TypeError: 类型错误,比如[1,2].split(‘.’);
- URIError: 给 encodeURI或 decodeURl()传递的参数无效,比如decodeURI(‘%2’)
- Error: 上面7种错误的基类,通常是开发者抛出
也就是说,代码运行时发生的上述8类错误,都可以被检测到。
unhandledrejection
Promise内部抛出的错误是无法被error捕获到的,这时需要用unhandledrejection事件。
// 初始化错误监控
initError(){
window.addEventListener('error', event=>{
this.error(error);
})
window.addEventListener('unhandledrejection', event=>{
this.error(new Error(event.reason), { type: 'unhandledrejection'})
})
}
React/Vue组件错误
成熟的框架库都会有错误处理机制,React和Vue也不例外
React的错误边界
它的使用很简单,就是一个带有特殊生命周期的类组件,用它把业务组件包裹起来。
这两个生命周期是getDerivedStateFromError和componentDidCatch,
// 定义错误边界
class ErrorBoundary extends React.Component {
state = { error: null }
static getDerivedStateFromError(error) {
return { error }
}
componentDidCatch(error, errorInfo) {
// 调用我们实现的SDK实例
insSDK.error(error, errorInfo)
}
render() {
if (this.state.error) {
return <h2>Something went wrong.</h2>
}
return this.props.children
}
}
...
<ErrorBoundary>
<BuggyCounter />
</ErrorBoundary>
Vue的错误边界
vue也有一个类似的生命周期来做这件事,不再赘述:errorCaptured
Vue.component('ErrorBoundary', {
data: () => ({ error: null }),
errorCaptured (err, vm, info) {
this.error = `${err.stack}\n\nfound in ${info} of component`
// 调用我们的SDK,上报错误信息
insSDK.error(err,info)
return false
},
render (h) {
if (this.error) {
return h('pre', { style: { color: 'red' }}, this.error)
}
return this.$slots.default[0]
}
})
...
<error-boundary>
<buggy-counter />
</error-boundary>
结束
以上是js常见错误三类错误监控