文章插图
在前端的 JAVAScript 开发中,发现开发者对于错误异常的处理普遍都比较简单粗暴,如果应用程序中缺少有效的错误处理和容错机制,代码的健壮性就无从谈起 。本文整理出了一些常见的错误异常处理的场景,旨在为前端的 JavaScript 错误异常处理提供一些基础的指导 。
Error 对象先来简单介绍一下 JavaScript 中的 Error 对象,通常 Error 对象由重要的两部分组成,包含了 error.message 错误信息和 error.stack 错误追溯栈 。
产生一个错误很简单,比如在 foo.js 中直接调用一个不存在的 callback 函数 。
// foo.jsfunction foo () {callback();}foo();
此时通过 Chrome 浏览器的控制台会展示如下的信息 。Uncaught ReferenceError: callback is not definedat foo (foo.js:2)at foo.js:5
其中 Uncaught ReferenceError: callback is not defined 就是 error.message 错误信息,而剩下的 at xxx 就是具体的错误追溯栈,在 Chrome 的控制台中,对错误的展示进行了优化 。如果我们通过 window.onerror 来捕获到该错误后将 Error 对象直接输出到页面中会展示出更原始的数据 。
<!-- 展示错误的容器 --><textarea id="error"></textarea>// 输出错误window.onerror = function (msg, url, line, col, err) {document.getElementById('error').textContent = err.message + 'nn' + err.stack;};
原始的错误数据中会展示出错误追溯栈中的 Source URL 。callback is not definedReferenceError: callback is not definedat foo (http://example.com/js-error/foo.js:2:5)at http://example.com/js-error/foo.js:5:1
有了错误追溯栈,就能通过发生错误的文件 Source URL 和错误在代码中的具体位置来快速定位到错误 。看起来好像很简单,但实际的开发中如何有效的捕获错误,如何有效的抛出错误都有一些需要注意的点,下面逐个的来讲解 。
window.onerror前端在捕获错误时都会通过绑定 window.onerror 事件来捕获全局的 JavaScript 执行错误,标准的浏览器在响应该事件时会依次提供 5 个参数 。
window.onerror = function(message, source, lineno, colno, error) { ... }
- message 错误信息
- source 错误发生时的页面 URL
- lineno 错误发生时的 JS 文件行数
- colno 错误发生时的 JS 文件列数
- error 错误发生时抛出的标准 Error 对象
绑定 window.onerror 事件时,事件处理函数的第 5 个参数在低版本浏览中或 JS 资源跨域场景下可能不是 Error 对象 。
在 Chrome 浏览器中如果页面加载的 JS 资源文件中存在跨域的 script 标签,在发生错误时会提示 Script error 而缺乏错误追溯栈 。
window.onerror 在响应跨域 JavaScript 错误时缺乏错误追溯栈时的 arguments 对象如下:
['Script error.','',0,0,null]
为了正常的捕获到跨域 JS 资源文件的错误,需要具备两个条件: 1. 为 JS 资源文件增加 CORS 响应头 。2. 通过 script 引用该 JS 文件时增加 crossorigin="anonymous" 的属性,如果是动态加载的 JS,可以写作 script.crossOrigin = true。window.onerror 能捕获一些全局的 JavaScript 错误,但还有不少场景在全局是捕获不到的 。
try/catchwindow.onerror 能捕获全局场景下的错误,如果已知一些程序的场景中可能会出现错误,这个时候一般会使用 try/catch 来进行捕获 。
但是在使用 try/catch 块时无法捕获异步错误,例如块中使用了 setTimeout。
try {setTimeout(function () {callTimeout();// callTimeout 未定义,会抛错}, 1000);}catch (err) {console.log('catch the error', err); // 不会被执行}
try/catch 在处理 setTimeout 这类异步场景时是无效的,执行时仍会抛错,catch 中的代码不会被执行 。虽然在 try/catch 中没有捕获到,此时如果有绑定 window.onerror 则会被全局捕获 。
由此可见,try/catch 应该是只能捕获 JS Event Loop 中同步的任务 。
如果想正确的捕获 setTimeout 中的错误,需要将 try/catch 块写到 setTimeout 的函数中 。
setTimeout(function () {try {callTimeout(); // callTimeout 未定义,不会抛错}catch (err) {console.log('catch the error', err); // 将会被执行}}, 1000);
PromisePromise 有自己的错误处理机制,通常 Promise 函数中的错误无法被全局捕获 。
推荐阅读
- win7提示explorer.exe应用程序错误的解决方法
- WordPress安装插件提示429错误完美解决办法
- 地震时动物的异常现象 地震前动物的异常反应
- 三步了解JavaScript的组成
- 试谈人们对茶的五个错误理解
- 13个需要知道的方法:使用 JavaScript 来操作 DOM
- |写材料常见的五个错误,你没犯过我请吃饭!!!
- FF与IE对javascript和CSS的区别?
- 以旧味论老茶 是错误的
- ?整只乳房切除手术