错误类型
编程经历中会遇到各式各样的错误,本文对错误类型做归类和小结。
Javascript 错误
JS是解释型语言,在代码运行过程中发生的错误归为以下6类:
- EvalError 与
eval()
有关的错误。例如在设置CSP禁用eval的页面中,使用eval就会报错。 - RangeError 数值变量或参数超出其有效范围。例如
new Array(-1)
。 - ReferenceError 无效引用。例如访问未定义的变量
x
。 - SyntaxError 语法错误。出现了就检查报错位置的代码吧。
- TypeError 变量或参数不属于有效类型。例如
null.val
。 - 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版本起才支持