Error - JavaScript Error 对象
Error
当运行时错误产生时,Error
对象会被抛出。Error
对象也可用于用户自定义的异常的基础对象。下面列出了各种内建的标准错误类型。
描述
当代码运行时的发生错误,会创建新的Error
对象,并将其抛出。
错误类型
除了通用的Error
构造函数外,JavaScript 还有其它类型的错误构造函数。对于客户端异常,详见异常处理语句。
EvalError
创建一个 error 实例,表示错误的原因:与eval()
有关。
RangeError
创建一个 error 实例,表示错误的原因:数值变量或参数超出其有效范围。
ReferenceError
创建一个 error 实例,表示错误的原因:无效引用。
SyntaxError
创建一个 error 实例,表示错误的原因:语法错误。
TypeError
创建一个 error 实例,表示错误的原因:变量或参数不属于有效类型。
URIError
创建一个 error 实例,表示错误的原因:给encodeURI()
或decodeURI()
传递的参数无效。
AggregateError
创建一个 error 实例,其中包裹了由一个操作产生且需要报告的多个错误。如:Promise.any()
产生的错误。
InternalError
非标准创建一个代表 Javascript 引擎内部错误的异常抛出的实例。如:递归太多。
构造函数
Error()
(en-US)创建一个新的Error
对象。
静态方法
Error.captureStackTrace()
非标准一个非标准的 V8 函数,用于在 Error 实例上创建stack
属性。
Error.stackTraceLimit
非标准一个非标准的 V8 数值属性,用于限制错误堆栈跟踪中包含堆栈帧数量。
Error.prepareStackTrace()
非标准可选一个非标准的 V8 函数,如果提供了这一函数,V8 JavaScript 引擎会调用该函数来抛出异常。这个函数允许用户提供自定义的堆栈跟踪格式。
实例属性
Error.prototype.message
错误消息。对于用户创建的Error
对象,这是构造函数的第一个参数提供的字符串。
Error.prototype.name
错误名称。这是由构造函数决定的。
Error.prototype.cause
(en-US)表示导致当前错误被抛出的原因——通常是另一个错误。对于用户创建的Error
对象,这是构造函数的第二个参数提供的值。
Error.prototype.fileName
非标准一个非标准的 Mozilla 属性,用于表示引发此错误的文件的路径。
Error.prototype.lineNumber
非标准一个非标准的 Mozilla 属性,用于表示引发此错误的代码所在的文件的行号。
Error.prototype.columnNumber
非标准一个非标准的 Mozilla 属性,用于表示引发此错误的代码在文件中所在行的列号。
Error.prototype.stack
非标准一个非标准的属性,用于堆栈跟踪。
实例方法
Error.prototype.toString()
返回表示该对象的字符串。覆盖了Object.prototype.toString()
方法。
示例
通常你会使用throw
关键字来抛出你创建的Error
对象。可以使用try...catch
结构来处理异常:
try { throw new Error('Whoops!') } catch (e) { console.error(e.name + ': ' + e.message) }
处理一个特定错误
你可以通过判断异常的类型来特定处理某一类的异常,即判断constructor
属性,当使用现代 JavaScript 引擎时,可使用instanceof
关键字:
try { foo.bar() } catch (e) { if (e instanceof EvalError) { console.error(e.name + ': ' + e.message) } else if (e instanceof RangeError) { console.error(e.name + ': ' + e.message) } // ... etc else { // If none of our cases matched leave the Error unhandled throw e; } }
区分相似的错误
有时,对于代码块的错误需要根据其原因进行不同的处理,但错误的原因又较为相似(例如:错误的类型和消息均相同)。
如果你无法控制原有错误的抛出,那么一种方法是捕获错误然后抛出一个新的错误,并在新的错误中给出更加具体的错误消息。原始错误应该被传递到新的Error
的构造函数的option
参数(cause
属性)中,这确保了原始的错误和堆栈追踪信息在上层的 try/catch 块中可用。
以下示例展示了两种方法会在失败时抛出相似的错误(doFailSomeWay()
和doFailAnotherWay()
):
function doWork() { try { doFailSomeWay(); } catch (err) { throw new Error('Failed in some way', { cause: err }); } try { doFailAnotherWay(); } catch (err) { throw new Error('Failed in another way', { cause: err }); } } try { doWork(); } catch (err) { switch(err.message) { case 'Failed in some way': handleFailSomeWay(err.cause); break; case 'Failed in another way': handleFailAnotherWay(err.cause); break; } }
备注:如果你在创建一个函数库,你应该使用错误原因来区分不同的错误——而不是要求你的函数库的使用者来解析错误消息。相关的示例,请参见提供错误原因(en-US)。
自定义错误类型也可以使用cause
属性,前提是通过super()
调用子类的构造函数时传递options
参数。
class MyError extends Error { constructor(/* some arguments */) { // Needs to pass both `message` and `options` to install the "cause" property. super(message, options); } }
自定义错误类型
你可能希望自定义基于Error
的异常类型,使得你能够throw new MyError()
并可以使用instanceof MyError
来检查某个异常的类型。这种需求的通用解决方法如下。
参考 StackOverflow 上关于“What's a good way to extend Error in JavaScript?”的讨论。
ES6 自定义错误类
警告: Babel 7 之前的版本可以处理CustomError
类方法,但类方法需要使用 Object.defineProperty()定义。否则,旧版本的 Babel 和其它转译器在没有额外配置的情况下将无法正确处理下面的代码。
备注:在使用 ES2015 的类时,一些浏览器会在堆栈跟踪中包含CustomError
构造函数。
class CustomError extends Error { constructor(foo = 'bar', ...params) { // Pass remaining arguments (including vendor specific ones) to parent constructor super(...params); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(this, CustomError); } this.name = 'CustomError'; // Custom debugging information this.foo = foo; this.date = new Date(); } } try { throw new CustomError('baz', 'bazMessage'); } catch(e) { console.error(e.name); // CustomError console.error(e.foo); // baz console.error(e.message); // bazMessage console.error(e.stack); // stacktrace }
ES5 自定义错误对象
警告:在使用原型声明时,所有浏览器都会在堆栈跟踪中包含CustomError
的构造函数。
function CustomError(foo, message, fileName, lineNumber) { var instance = new Error(message, fileName, lineNumber); instance.foo = foo; Object.setPrototypeOf(instance, CustomError.prototype); if (Error.captureStackTrace) { Error.captureStackTrace(instance, CustomError); } return instance; } Object.setPrototypeOf(CustomError.prototype, Error.prototype); Object.setPrototypeOf(CustomError, Error); CustomError.prototype.name = 'CustomError'; try { throw new CustomError('baz', 'bazMessage'); } catch(e) { console.error(e.name); // CustomError console.error(e.foo); // baz console.error(e.message); // bazMessage }
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!