巩固Error和自定义Error

392 阅读4分钟

前言

是否对于Error的了解只有throw new Error('string')err.message,不久前我的理解也就这么多,但是一个请求拦截抛出异常困住我了,当时我想的是throw new Error(JSON.stringify(res.data)),这样处理异常的时候再使用JSON.parse()下就可以获得请求错误的信息。显然这个做法是不对的,这就是了解的少才会有这样的想法。

官方文档:Error - JavaScript | MDN (mozilla.org)

正文

Error()构造函数

Error()  构造函数能够创建一个包含错误信息的对象。

new Error()
new Error(message)
new Error(message, options)
new Error(message, fileName)
new Error(message, fileName, lineNumber)
Error()
Error(message)
Error(message, options)
Error(message, fileName)
Error(message, fileName, lineNumber)

fileNamelineNumber都是非标准属性,使用要看浏览器支持不支持。通常我们只会使用到message,这可能就是为什么只了解到这的原因。 image.png

Error实例对象属性

  • 标准属性
    • cause 数据属性指示导致该错误的具体原始原因,它通过 options.cause 参数被传入 Error()构造函数,并且有可能不存在,cause 的值可以是任何类型。

    • message 属性是有关错误信息

    • name 属性表示 error 类型的名称。初始值为"Error".

  • 非标准,看浏览器支持不支持
    • columnNumber属性包含引发此错误的文件行中的列

    • fileName 属性包含引发此错误的文件的路径

    • **lineNumber 属性的值为抛出错误的代码在其源文件中所在的行号。

几种Error类型

EvalError

EvalError 对象代表了一个关于 eval() 全局函数的错误。此异常不再会被 JavaScript 抛出,但是 EvalError 对象仍然存在,以保持兼容性。

try {
  throw new EvalError("Hello", "someFile.js");
} catch (e) {
  console.log(e instanceof EvalError); // true
  console.log(e.message); // "Hello"
  console.log(e.name); // "EvalError"
}
InternalError

InternalError 对象表示出现在 JavaScript 引擎内部的错误。通常描述某种数量过多的情况

非标准:  该特性是非标准的,请尽量不要在生产环境中使用它!

  • "too many switch cases"(过多 case 子句);
  • "too many parentheses in regular expression"(正则表达式中括号过多);
  • "array initializer too large"(数组初始化器过大);
  • "too much recursion"(递归过深)。
RangeError

RangeError 对象表示一个特定值不在所允许的范围或者集合中的错误。

function check(n) {
  if (!(n >= -500 && n <= 500)) {
    throw new RangeError("The argument must be between -500 and 500.");
  }
}

try {
  check(2000);
} catch (error) {
  if (error instanceof RangeError) {
    // 处理错误
  }
}
function check(value) {
  if (!["apple", "banana", "carrot"].includes(value)) {
    throw new RangeError(
      'The argument must be an "apple", "banana", or "carrot".',
    );
  }
}

try {
  check("cabbage");
} catch (error) {
  if (error instanceof RangeError) {
    // 处理错误
  }
}
try {
  let π = 3.1415925
  π.toFixed(1000)
} catch (e) {
  console.log(e.name) //RangeError
  console.log(e.message) //toFixed() digits argument must be between 0 and 100
}
ReferenceError

ReferenceError(引用错误)对象代表当一个不存在(或尚未初始化)的变量被引用时发生的错误。

try {
  let a = undefinedVariable;
} catch (e) {
  console.log(e instanceof ReferenceError); // true
  console.log(e.message); // "undefinedVariable is not defined"
  console.log(e.name); // "ReferenceError"
}
SyntaxError

SyntaxError(语法错误)对象代表尝试解析不符合语法的代码的错误。当 Javascript 引擎解析代码时,遇到了不符合语法规范的标记(token)或标记顺序,则会抛出 SyntaxError

const fn = (data) {}

image.png

try {
  eval('let a ==== 5'); // 语法错误
} catch (e) {
  if (e instanceof SyntaxError) {
    console.log(e.message); // 输出 Unexpected token '==='
    console.log(e.name); // 输出 "SyntaxError"
  }
}
TypeError

TypeError(类型错误)对象通常(但并不只是)用来表示值的类型非预期类型时发生的错误。

  • 传递给运算符的操作数或传递给函数的参数与预期的类型不兼容;
  • 尝试修改无法更改的值;
  • 尝试以不适当的方法使用一个值。
try {
  const obj = {}
  obj.test()
} catch (e) {
  console.log(e.message); // obj.test is not a function
  console.log(e.name); // 输出 TypeError
}
URIError

URIError 对象用来表示以一种错误的方式使用全局 URI 处理函数而产生的错误。

try {
  decodeURIComponent("%");
} catch (e) {
  console.log(e instanceof URIError); // true
  console.log(e.message); // "URI malformed"
  console.log(e.name); // "URIError"
}

自定义Error

当异常只有一种状态时我们可以使用throw new Error('string')来处理,当需要明确具体的原因时,我们可以使用cause属性或者自定义Error来存储导致错误的原因,比如请求

在处理异常时使用读取cause属性就可以


  throw new Error('HTTP error ' + res.statusCode, {
    cause: {
      code: res.data.code,
      msg: res.data.msg
    }
  })

看一下自定义Error

class CustomError extends Error {
  constructor(message, extra) {
    super(message);
    this.name = 'CustomError';
    this.extra = extra;
  }
}

try {
  throw new CustomError('This is a custom error', {
    code: 500,
    msg: '服务器错误'
  });
} catch (e) {
  console.log(e.name); // 输出 "CustomError"
  console.log(e.message); // 输出 "This is a custom error"
  console.log(e.extra); // 输出 {code: 500, msg: '服务器错误'}
}

结语

感兴趣的可以去试试