在平时的工作,js报错是比较常见的一个情景,当出现错误的时候,用户上报问题我们往往需要去定位问题的原因,但是因为错误存在于用户的客户端,所以我们没法很好的拿到错误的信息,所以如果当我们前端js出现异常的时候能及时上报的话,那我们的问题就比较好解决了。
其实讲到上面的需求,我们可能就知道我们想要的其实就是一个前端的异常监控平台,现在市面上有很多这样的平台:前端异常监控平台对比,网上比较多推荐的是:sentry,它对异常数据的收集和分析更加完善,如果公司有条件私有化部署的话比较推荐使用。
我们先不考虑使用现成的平台,因为我们想要的功能比较简单,而且部署一套监控平台公司不一定允许,所以可以考虑在自己项目中进行处理,不引用第三方的平台。当然有条件我还是建议不要自己造轮子了。
那这里就会涉及到几个方面的处理:
try..catch
的捕获前端异常其实无非两种:
对于第一种call后端API接口异常一般都是在请求时候触发的,而我们现在一般都是使用axios
或者 umi-request
去请求后台的。
如果你用 Promise
的写法,则用 .catch
捕获
request(url, {
method: 'GET'
}).catch((err) => {
// err 就是捕获到的错误对象
handleError(err);
});
如果你用 async/await
的写法,则用 try..catch..
捕获:
async () => {
try {
await request(url, {
method: 'GET'
})
} catch (err) {
//进行异常采集
handleError(err);
}
};
当然我们不建议这种方式,因为埋点的地方太多了,很多冗余代码,对现有代码的侵入性也很强。
我们一般都是使用拦截器中捕获异常来捕获异常。
比如在umi-request
中我们可以能会这么做,定义一个错误拦截器来捕获异常
export const errorHandler = function (error: ResponseError<ErrorResponse>) {
//进行异常采集
handleError(error);
throw error;
};
export const request: RequestConfig = {
errorHandler,
};
对于React来说,可以使用React的Error Boundary来处理渲染子组件期间的同步错误,错误边界是一种 React 组件,这种组件可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件树。错误边界在渲染期间、生命周期方法和整个组件树的构造函数中捕获错误。
具体如何使用可以参考官网:Error Boundaries
还可以参考:HOW TO HANDLE ERRORS EFFICIENTLY IN REACT
但是错误边界有很多场景是无法捕获到异常的:
所以总结来说:仅处理渲染子组件期间的同步错误
所以除此之外还可以通过监听onerror
事件来捕获异常,可以参考:搭建前端监控,如何采集异常数据?
window.addEventListener('error', function(event) { ... })
这个应该很好解决,只要我们在前端把我们的异常信息都封装好,然后通过API把数据上报到后端服务即可。
主要的难度其实在于前端异常数据的组装,以下有一些比较重要的信息需要一并记录,方便我们以后更好查阅。
对于接口异常来说有以下几项:
而对于前端异常来说有以下几项
同时在组装和上报数据的时候又存在几个问题:
对于处理上报异常和通知可以采取如下方式
React Error Handling and Logging Best Practices
How do I set up custom error handling with React?
HOW TO HANDLE ERRORS EFFICIENTLY IN REACT
Logging and error management best practices in SSR apps
Client-side error logging in React web application
React捕获错误 getDerivedStateFromError()和componentDidCatch()
React Logging and Error Handling Best Practices