Error类


一个普通的 JavaScript Error 对象不会表述错误发生的具体原因。Error 对象会捕捉一个详细说明被实例化的 Error 对象在代码中的位置的“堆栈跟踪”,并可能提供对此错误的文字描述。

所有由 Node.js 产生的系统和 JavaScript 错误都继承实例化或继承自 Error 类。

new Error(message)

新建一个 Error 实例并设置它的 error.message 属性以提供文本信息。如果 message 传的是一个对象,则会通过 message.toString() 生成文本信息。error.stack 属性会表明 new Error() 在代码中的位置。
堆栈跟踪是根据 V8 的堆栈跟踪 API 生成的。堆栈跟踪只会取(a)异步代码开始执行前或(b)Error.stackTraceLimit 属性给出的栈帧中的最小项。

Error.captureStackTrace(targetObject[, constructorOpt])

当访问调用 Error.captureStackTrace() 方法所返回的表示代码中的位置的字符串时,会在 targetObject 上创建一个 .stack 属性。

  1. const myObject = {};
  2. Error.captureStackTrace(myObject);
  3. myObject.stack // similar to `new Error().stack`

堆栈跟踪的第一行会是前缀被替换成 ErrorType: messagetargetObject.toString() 的调用结果。

可选的 constructorOpt 接受一个函数作为其参数。如果提供了该参数,则 constructorOpt 以前包括自身在内的全部栈帧都会被其生成的堆栈跟踪省略。

constructorOpt 用在向最终用户隐藏错误生成的具体细节时非常有用。例如:

  1. function MyError() {
  2. Error.captureStackTrace(this, MyError);
  3. }
  4. // Without passing MyError to captureStackTrace, the MyError
  5. // frame would should up in the .stack property. by passing
  6. // the constructor, we omit that frame and all frames above it.
  7. new MyError().stack

Error.stackTraceLimit

Error.stackTraceLimit 属性用于指定堆栈跟踪所收集的栈帧数量(无论是由 new Error().stack 还是由 Error.captureStackTrace(obj) 产生的)。

默认值为 10 ,但可以设置成任何有效 JavaScript 数值。这个修改会影响到值被改变后捕捉到的所有堆栈跟踪。

如果设置成一个非数值或负数,堆栈跟踪将不会捕捉任何栈帧。

error.message

返回由 new Error(message) 设置的用来描述错误的字符串。这个传递给构造函数的 message 也将出现在 Error 的堆栈跟踪的第一行。然而,在 Error 对象创建后改变这个属性可能不会改变堆栈跟踪的第一行。

  1. const err = new Error('The message');
  2. console.log(err.message);
  3. // Prints: The message

error.stack

返回一个描述 Error 实例在代码中的位置的字符串。

例如:

  1. Error: Things keep happening!
  2. at /home/gbusey/file.js:525:2
  3. at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)
  4. at Actor.<anonymous> (/home/gbusey/actors.js:400:8)
  5. at increaseSynergy (/home/gbusey/actors.js:701:6)

第一行会被格式化为 <error class name>: <error message> ,并且随后跟着一系列栈帧(每一行都会以 “at “ 开头)。每一帧都描述了一个代码中导致错误生成的调用点。V8 引擎会尝试显示每个函数的名称(变量名、函数名或对象的方法名),但偶尔也可能找不到一个合适的名称。如果 V8 引擎没法确定一个函数的名称,在该栈帧中只会显示仅有的位置信息。否则,在位置信息的附近将会显示已确定的函数名。

注意,这对由 JavaScript 函数产生的栈帧非常有用。例如,在自身是一个 JavaScript 函数的情况下,通过同步执行一个名为 cheetahify 的 C++ 插件时,代表 cheetahify 回调的栈帧将不会出现在当前的堆栈跟踪里:

  1. const cheetahify = require('./native-binding.node');
  2. function makeFaster() {
  3. // cheetahify *synchronously* calls speedy.
  4. cheetahify(function speedy() {
  5. throw new Error('oh no!');
  6. });
  7. }
  8. makeFaster(); // will throw:
  9. // /home/gbusey/file.js:6
  10. // throw new Error('oh no!');
  11. // ^
  12. // Error: oh no!
  13. // at speedy (/home/gbusey/file.js:6:11)
  14. // at makeFaster (/home/gbusey/file.js:5:3)
  15. // at Object.<anonymous> (/home/gbusey/file.js:10:1)
  16. // at Module._compile (module.js:456:26)
  17. // at Object.Module._extensions..js (module.js:474:10)
  18. // at Module.load (module.js:356:32)
  19. // at Function.Module._load (module.js:312:12)
  20. // at Function.Module.runMain (module.js:497:10)
  21. // at startup (node.js:119:16)
  22. // at node.js:906:3

其中的位置信息会以下形式出现:

  • native,如果栈帧产生自 V8 引擎内部(比如,[].forEach)。

  • plain-filename.js:line:column,如果栈帧产生自 Node.js 内部。

  • /absolute/path/to/file.js:line:column,如果栈帧产生自用户程序或其依赖。

代表堆栈跟踪的字符串是在访问 error.stack 属性时才被生成的。

堆栈跟踪捕获的栈帧的数量是由 Error.stackTraceLimit 或当前事件循环可用的栈帧数量中的最小值界定。

系统级的错误由已传参的 Error 实例产生,详见此处