百科狗-知识改变命运!
--

Error - JavaScript Error 对象

梵高1年前 (2023-11-21)阅读数 23#技术干货
文章标签错误

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 - JavaScript Error 对象

表示导致当前错误被抛出的原因——通常是另一个错误。对于用户创建的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

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)