错误处理
了解在 JS 中错误的处理
抛出的错误基本信息
我们使用 JSON.parse 来制造一个错误
try {
JSON.parse('')
}
catch (e) {
console.log(e)
}执行后有如下输出:
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at file:///path/to/project/src/error.js:13:8
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)如果我们希望得到 e 的内容,需要去读取 e.stack 而非 e 本身。这是因为 console.log 会对 e 进行处理,实际打印的就是 e.stack
catch (e) {
fs.writeFileSync('./error.log', e.stack)
}除此之外,e 对象还有另外两个属性 e.name 和 e.message。分别是错误的名称和错误的描述。可以看出 e.stack 是包含这两部分的:
catch (e) {
console.log('name:', e.name) //=> name: SyntaxError
console.log('message:', e.message) //=> message: Unexpected end of JSON input
}cause
es2020 扩展了 Error 对象的属性,允许在抛出错误的时候,额外传入一个 cause 参数,它可以是任何类型
cause 的出现,可以让 e.message 完全承载的自定义错误的类型,而相关更具体的错误原因叫由 cause 携带
它可以是一个携带业务上下文的对象
function makeRSA(p, q) {
if (!Number.isInteger(p) || !Number.isInteger(q)) {
throw new Error("RSA key generation requires integer inputs.", {
cause: { code: "NonInteger", values: [p, q] },
});
}
if (!areCoprime(p, q)) {
throw new Error("RSA key generation requires two co-prime integers.", {
cause: { code: "NonCoprime", values: [p, q] },
});
}
// rsa algorithm…
}也可以携带来自更深层的错误原因,这方便我们追踪、定位相关代码:
function doFailSomeWay() {
throw new Error('TYPE_A_ERROR', { cause: 'doFailSomeWay' })
}
function doFailAnotherWay() {
throw new Error('TYPE_B_ERROR', { cause: 'doFailAnotherWay' })
}
function doWork() {
try { doFailSomeWay() } catch (err) {
throw new Error('TYPE_C_ERROR', { cause: err })
}
try { doFailAnotherWay() } catch (err) {
throw new Error('TYPE_D_ERROR', { cause: err })
}
}
try { doWork() } catch (err) {
console.log(err)
switch (err.message) {
case 'TYPE_C_ERROR': handleFailC(err.cause); break
case 'TYPE_D_ERROR': handleFailD(err.cause); break
}
}
function handleFailC(err) { }
function handleFailD(err) { }上面代码执行结果:
Error: TYPE_C_ERROR
at doWork (/path/to/project/src/main.ts:11:11)
at <anonymous> (/path/to/project/src/main.ts:20:3)
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
[cause]: Error: TYPE_A_ERROR
at doFailSomeWay (/path/to/project/src/main.ts:2:9)
at doWork (/path/to/project/src/main.ts:9:9)
at <anonymous> (/path/to/project/src/main.ts:20:3)
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
[cause]: 'doFailSomeWay'
}
}错误层级展示的兼容性
兼容性方面,NodeJs 在 console 能够展示出错误的层级关系,而各大浏览器除了火狐之外,其他还待支持 (截止2024.4.3)
堆栈解析
可以使用 antfu/error-stack-parser-es 进行堆栈的解析
import { parse } from 'error-stack-parser-es/lite'
const stacktrace = parse(new Error('BOOM!'))
// [{ file: 'file.js', name: 'method', line: 1, col: 2}]如果是为了追踪某一对象,可以使用进一步封装的包 antfu/trace-record