JavaScript / TypeScript:保留错误原因的标准方法

Syl*_*rch 13 javascript error-handling stack-trace typescript

我有 Java 开发背景,而且对 JavaScript/TypeScript 还很陌生。

是否有标准方法来管理和保留 JavaScript/TypeScript 中错误的原因?

我的目的是当我将一个 Error 包装到另一个 Error 中时获得完整的堆栈跟踪;有点像 Java 异常堆栈跟踪:

Message of exception 1
...
Caused by: Message of exception 2
...
Caused by: Message of the root exception
Run Code Online (Sandbox Code Playgroud)

我尝试了这段代码,但err1没有保留以下参考err2

// CODE
try {
    try {
        throw new Error("Error no2");
    } catch (err2) {
        console.log("========================================");
        console.log(err2);
        throw new Error("Error no1");
    }
} catch (err1) {
    console.log("========================================");
    console.log(err1);
}
Run Code Online (Sandbox Code Playgroud)
// CONSOLE OUTPUT
$ node test.ts 
========================================
Error: Error no2
    at Object.<anonymous> (/tmp/test.ts:3:15)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
    at internal/main/run_main_module.js:17:11
========================================
Error: Error no1
    at Object.<anonymous> (/tmp/test.ts:7:15)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
    at internal/main/run_main_module.js:17:11
Run Code Online (Sandbox Code Playgroud)

此外,我没有找到任何cause在 Error 类中命名的属性。有一个stack属性,但我认为更改它是一个不好的做法。

谢谢!

Chr*_* HG 10

2021 答案:现在有一种标准方法来管理和保持错误原因。构造函数Error()现在可以接受一个options对象作为第二个参数。该options对象应该具有一个cause属性,该属性通常是另一个属性Error,但并非必须如此。

例子

throw new Error('Outer Error', {cause: new Error('Inner Error')});
Run Code Online (Sandbox Code Playgroud)

支持

截至撰写本文时(2021 年 10 月),Firefox、Chrome 和 Safari 支持新的构造函数。要了解其原因,Error您需要询问其cause属性。此外,在 Firefox 中,我们在控制台中获得了一些额外信息,例如

Uncaught Error: Outer Error
    <anonymous> debugger eval code:1
Caused by: Error: Inner Error
    <anonymous> debugger eval code:1
Run Code Online (Sandbox Code Playgroud)

Edge 目前只会忽略第二个构造函数属性。

来源

Mozilla 文档: https://developer.mozilla.org/en-US/docs/web/javascript/reference/global_objects/error

ECMAScript 提案:https://github.com/tc39/proposal-error-cause


tfr*_*oli 1

我一直在这里使用克里斯蒂安答案的修改版

class TraceableError extends Error {
  trace: Error;

  constructor(message?: string, innerError?: Error) {
    super(message); 
    this.trace = innerError;

    const actualProto = new.target.prototype;

    if (Object.setPrototypeOf) { Object.setPrototypeOf(this, actualProto); } 
    else { this.__proto__ = actualProto; } 
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你会像这样扔

try {
    try {
        throw new Error("Error no2");
    } catch (err2) {
        console.log("========================================");
        console.log(err2);
        throw new TraceableError ("Error no1", err2);
    }
} catch (err1) {
    console.log("========================================");
    console.log(err1);
}
Run Code Online (Sandbox Code Playgroud)

注意,如果没有捕获,trace新错误的部分将不会输出到控制台。