Skip to content
导航

错误类型

编程经历中会遇到各式各样的错误,本文对错误类型做归类和小结。

Javascript 错误

JS是解释型语言,在代码运行过程中发生的错误归为以下6类:

  1. EvalError 与eval()有关的错误。例如在设置CSP禁用eval的页面中,使用eval就会报错。
  2. RangeError 数值变量或参数超出其有效范围。例如 new Array(-1)
  3. ReferenceError 无效引用。例如访问未定义的变量 x
  4. SyntaxError 语法错误。出现了就检查报错位置的代码吧。
  5. TypeError 变量或参数不属于有效类型。例如null.val
  6. URIError 给 encodeURI()decodeURI() 传递的参数无效。例如 decodeURI('%%')

在ES中增加了一种新的错误类型 AggregateError,用于批量抛出错误。

系统错误

使用Node.js fs 模块操作文件系统时,会遇到的错误类型:

  • EACCES - Permission denied
  • EADDRINUSE - Address already in use
  • ECONNRESET - Connection reset by peer
  • EEXIST - File exists
  • EISDIR - Is a directory
  • EMFILE - Too many open files in system
  • ENOENT - No such file or directory
  • ENOTDIR - Not a directory
  • ENOTEMPTY - Directory not empty
  • ENOTFOUND - DNS lookup failed
  • EPERM - Operation not permitted
  • EPIPE - Broken Pipe
  • ETIMEDOUT - Operation timed out

断言错误

Node.js 通过 assert 模块提供了基本的单元测试能力。

当测试断言不通过时,会抛出 AssertionError 错误。

js
import assert from 'node:assert'
assert.equal(1, 2, '1==2')

报错:

shell
AssertionError [ERR_ASSERTION]: 1==2
    at CallTracker...
  generatedMessage: false,
  code: 'ERR_ASSERTION',
  actual: 1,
  expected: 2,
  operator: '=='
}

自定义错误

使用 Error 构造函数,可以自定义错误对象

js
const errObj = new Error('custom error.')
console.error(errObj)

这样只会在控制台打印错误,不会中断JS运行

抛出错误

通常错误会中断JS运行,可以通过 throw 关键字来实现

js
throw 1 + 2  // 3
  • throw 后表达式的执行结果,会作为错误信息抛出
  • throw 会阻止后续代码运行

捕获错误

try catch 表达式用于捕获同步代码错误,以及在 async 函数体中捕获 await 异步错误。

js
try{
  throw new Error('custom error.')
}catch(error){
  console.error(error)
}

ES2019、Node.js v10 起,不关心错误仅为捕获错误,可以省略error参数,简化为 try {} catch {}

自定义错误类型

通过继承 Error 类,可以自定义错误类型

js
class MyError extends Error {
  constructor(message, options) {
    super(message, options);
  }
}

自定义错误类型可以便于区分错误,同样是使用类的语法:

js
try{
  throw new MyError('error.')
}catch(error){
  if(error instanceof MyError){
    // 处理MyError
  }
}

使用 cause 嵌套错误信息

错误信息是可以通过 Error.prototype.cause 层层包裹、嵌套的,用于为原错误补充错误信息

js
try{
    throw new Error('1')
}catch(err1){
    try{
        throw new Error('2', { cause: err1 })
    }catch(err2){
        try{
            throw new Error('3', { cause: err2 })
        }catch(err3){
            console.error(err3)
        }
    }
}

ES2022,Node.js v16版本起才支持