前端如何优雅的捕获异常 ???
一、为什么要捕获异常
我们开发一个产品,不仅要做到开发没有问题,后期维护也要没啥问题;
我们没法去拿着用户的设备去判断到底什么问题,但是一定要加监控,可以在后台及时发现并处理异常;
我们在开发项目的时候要做到及时做一下完整性分析,包括日志平台,监控平台,前后端都增加一层捕获,有利于我们发现问题;
- 增强用户体验;
- 远程定位问题;
- 未雨绸缪,及早发现问题;
- 无法复线问题,尤其是移动端,机型,系统都是问题;
- 完善的前端方案,前端监控系统;
二、需要处理异常哪些异常
- js语法,代码异常;
- fetch接口调用失败,或者格式解析错误;
- js,image等静态文件加载失败;
- 页面崩溃,白屏等
三、下面我们从以上几个方面给出相应的方案
1、js语法,代码问题
第一种,使用js 的onerror事件监听
/** * @param {String} message 错误信息 * @param {String} source 出错文件 * @param {Number} lineno 行号 * @param {Number} colno 列号 * @param {Object} error Error对象(对象) */ window.onerror = function(message, source, lineno, colno, error) { console.log('捕获到异常:',{message, source, lineno, colno, error}); }
第二种,typescript我们尽量使用"?.","??"等3.8以后版本提供的方法,及时判断错误
2、fetch接口调用失败,或者格式解析错误
接口使用try catch 捕获错误,以及返回正确的格式
try { let name = 'jartto'; console.log(nam); } catch(e) { console.log('捕获到异常:',e); }
结合上面在我们fetch方法中增加一些日志捕获,包括请求以及返回都要增加监听
请求部分监听
/** * 返回错误检查 * @param response 返回实例 */ export const checkResponse = (response: Response) => { const { status, url } = response; if (status >= 500 && status < 600) {
addErrToStorage(`url:${url}|status:${status}`); window.location.href = '/50x.html'; return false; } else if (status >= 400 && status < 500) { addErrToStorage(`url:${url}|status:${status}`); window.location.href = '/40x.html'; return false; } return true; }
返回部分方法
/** * 将错误信息发送给后台 * @param message 错误信息 */ export const postErrLog = (message: string | object) => { if (typeof message === 'object') { message = JSON.stringify(message) } return Fetch({ url: 'xxxx', data: { status: 'error', message }, method: 'POST', catchErr: false, checkCode: false, needErrToast: false }) }
3、静态文件加载失败问题
通过nginx配置一些特定图片,文件,如果找不到nginx去跳转至指定文件
4、页面崩溃,白屏等
第一种,React项目封装高阶错误捕获组件,包括我们的根组件
componentDidCatch(error, info) {
console.log(error, info);
}
第二种,React项目可以使用错误边界Error Boundary,通过框架进行捕获,将日志发送给服务器
具体详见 https://www.cnblogs.com/cxyqts/p/13176164.html
第三种,vue项目可以使用errorHandler,也是框架自带捕获
Vue.config.errorHandler = (err, vm, info) => { console.error('通过vue errorHandler捕获的错误'); console.error(err); console.error(vm); console.error(info); }
第四种,创建img标签,动态调用接口
new Image().src = 'http://localhost:7001/monitor/error'+ '?info=xxxxxx'