说一下错误监控的实现,错误监控的正确使用方式,日志如何分等级?
错误分类
运行时错误:这个错误往往是在写代码时造成的。如语法错误、逻辑错误等等,这种错误一般在测试过程中也能够发现
资源加载错误:这个错误通常是找不到文件或者是文件加载超时造成的。
错误捕获
- 代码错误捕获
try { //运行可能出错的代码 } catch (e) { //捕获错误 }
window.onerror = function () { //捕获错误 }; /** 同步错误 * @param {String} msg 错误信息 * @param {String} url 出错文件 * @param {Number} row 行号 * @param {Number} col 列号 * @param {Object} error 错误详细信息 */ window.onerror = function (msg, url, row, col, error) { console.log("我知道错误了"); console.log({ msg, url, row, col, error, }); return true; }; error; //异步错误 window.onerror = function (msg, url, row, col, error) { console.log("我知道异步错误了"); console.log({ msg, url, row, col, error, }); return true; }; setTimeout(() => { error; });
需要注意的是,window.onerror 函数只有在返回 true 的时候,异常才不会向上抛出,否则即使是知道异常的发生控制台还是会显示 Uncaught Error: xxxx。
由于网络请求异常不会事件冒泡,因此必须在捕获阶段将其捕捉到才行,但是这种方式虽然可以捕捉到网络请求的异常,但是无法判断 HTTP 的状态是 404 还是其他比如 500 等等,所以还需要配合服务端日志才进行排查分析才可以。
<script> window.addEventListener('error', (msg, url, row, col, error) => { console.log('我知道 404 错误了'); console.log( msg, url, row, col, error ); return true; }, true); </script> <img src="./404.png" alt="">
在实际的使用过程中,onerror 主要是来捕获预料之外的错误,而 try…catch 则是用来在可预见情况下监控特定的错误,两者结合使用更加高效。
- 资源加载错误
var img = document.getElementById("#img"); img.onerror = function () { // 捕获错误 };
利用 window 的 error 事件代理,但是需要注意的是 error 事件是不冒泡的,可以使用事件捕获进行代理
window.addElementListener( "error", function () { // 捕获错误 }, true );
错误上报
常见的错误上报有两种:ajax、image 对象(推荐)
ajax 上报就是在上文注释错误捕获的地方发起 ajax 请求,来向服务器发送错误信息
// 利用image对象 function report(error) { var reportUrl = "http://xxxx/report"; new Image().src = reportUrl + "?" + "error=" + error; }
跨域 js 文件错误获取
跨域 js 文件获取是有限制的,如果想获取其他域下的 js 错误需要在 script 标签中添加 crossorgin 属性,然后服务器要设置 header('Access-Control-Allow-Origin');
// http://localhost:8080/index.html <script> window.onerror = function (msg, url, row, col, error) { console.log('我知道错误了,也知道错误信息'); console.log({ msg, url, row, col, error }) return true; }; </script> <script src="http://localhost:8081/test.js" crossorigin></script> // http://localhost:8081/test.js <script> setTimeout(() => { console.log(error); }); </script>
日志分等级
日志,是我们输出系统消息的一些节点,但是由于业务、编码优先级的不同,日志通常通过定义不同的基本来进行输出
比如可以参考 chrome 的输出划分:
- log 普通日志
- info 普通信息
- warn 警告值息
- error 错误值息