错误

Error 对象在运行时错误发生时被抛出。Error 对象也可以用作用户定义异常的基本对象。请参见下文了解标准内置错误类型。

描述

运行时错误会导致创建并抛出新的 Error 对象。

Error 是一个可序列化对象,因此可以使用 structuredClone() 克隆它,或使用 postMessage()工作线程 之间复制它。

错误类型

除了通用 Error 构造函数之外,JavaScript 中还有其他核心错误构造函数。对于客户端异常,请参见 异常处理语句

EvalError

创建一个表示关于全局函数 eval() 发生的错误的实例。

RangeError

创建一个表示数值变量或参数超出其有效范围时发生的错误的实例。

ReferenceError

创建一个表示解除对无效引用的引用时发生的错误的实例。

SyntaxError

创建一个表示语法错误的实例。

TypeError

创建一个表示变量或参数不是有效类型时发生的错误的实例。

URIError

创建一个表示当 encodeURI()decodeURI() 传递无效参数时发生的错误的实例。

AggregateError

创建一个表示多个错误包装在一个错误中的实例,当需要由某个操作报告多个错误时,例如由 Promise.any() 报告。

InternalError 非标准

创建一个表示 JavaScript 引擎内部错误发生时抛出的错误的实例。例如“递归过多”。

构造函数

Error()

创建一个新的 Error 对象。

静态方法

Error.captureStackTrace() 非标准

一个非标准的 V8 函数,它在 Error 实例上创建 stack 属性。

Error.stackTraceLimit 非标准

一个非标准的 V8 数值属性,它限制了在错误堆栈跟踪中包含多少个堆栈帧。

Error.prepareStackTrace() 非标准 可选

一个非标准的 V8 函数,如果由用户代码提供,则由 V8 JavaScript 引擎为抛出的异常调用,允许用户为堆栈跟踪提供自定义格式。

实例属性

这些属性定义在 Error.prototype 上,并由所有 Error 实例共享。

Error.prototype.constructor

创建实例对象的构造函数。对于 Error 实例,初始值为 Error 构造函数。

Error.prototype.name

表示错误类型的名称。对于 Error.prototype.name,初始值为 "Error"。子类,如 TypeErrorSyntaxError 提供了自己的 name 属性。

Error.prototype.stack 非标准

一个非标准的堆栈跟踪属性。

这些属性是每个 Error 实例的自身属性。

cause

指示抛出当前错误的原因的错误原因 - 通常是另一个捕获的错误。对于用户创建的 Error 对象,这是作为构造函数的第二个参数的 cause 属性提供的值。

columnNumber 非标准

一个非标准的 Mozilla 属性,用于引发此错误的行中的列号。

fileName 非标准

一个非标准的 Mozilla 属性,用于引发此错误的文件的路径。

lineNumber 非标准

一个非标准的 Mozilla 属性,用于引发此错误的文件的行号。

message

错误消息。对于用户创建的 Error 对象,这是作为构造函数的第一个参数提供的字符串。

实例方法

Error.prototype.toString()

返回表示指定对象的字符串。覆盖 Object.prototype.toString() 方法。

示例

抛出通用错误

通常,您会创建一个 Error 对象,目的是使用 throw 关键字引发它。您可以使用 try...catch 结构处理错误

js
try {
  throw new Error("Whoops!");
} catch (e) {
  console.error(`${e.name}: ${e.message}`);
}

处理特定错误类型

您可以选择仅处理特定错误类型,方法是使用 instanceof 关键字测试错误类型

js
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对象。原始错误应作为构造函数的options参数中的cause属性传递给新的Error。这确保了原始错误和堆栈跟踪可供更高级别的try/catch块使用。

下面的示例展示了这一点,其中两个方法(doFailSomeWay()doFailAnotherWay())可能会以类似的错误失败。

js
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;
  }
}

注意:如果您正在制作库,则应优先使用错误原因来区分发出的不同错误,而不是要求您的用户解析错误消息。请参阅错误原因页面以获取示例。

自定义错误类型也可以使用cause属性,前提是子类的构造函数在调用super()时传递options参数。Error()基类构造函数将读取options.cause并在新的错误实例上定义cause属性。

js
class MyError extends Error {
  constructor(message, options) {
    // Need to pass `options` as the second parameter to install the "cause" property.
    super(message, options);
  }
}

console.log(new MyError("test", { cause: new Error("cause") }).cause);
// Error: cause

自定义错误类型

您可能希望定义自己的从Error派生的错误类型,以便能够throw new MyError()并在异常处理程序中使用instanceof MyError来检查错误类型。这将使错误处理代码更清晰、更一致。

请参阅StackOverflow上的"在JavaScript中扩展Error的良好方法是什么?",以获取深入讨论。

警告:内置子类化无法可靠地转换为ES6之前的代码,因为在没有Reflect.construct()的情况下,无法使用特定的new.target构造基类。您需要其他配置或手动在构造函数的末尾调用Object.setPrototypeOf(this, CustomError.prototype);否则,构造的实例将不是CustomError实例。请参阅TypeScript常见问题解答以获取更多信息。

注意:某些浏览器在使用ES2015类时会在堆栈跟踪中包含CustomError构造函数。

js
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
}

规范

规范
ECMAScript语言规范
# sec-error-objects

浏览器兼容性

BCD表格仅在浏览器中加载

另请参阅