如何在try-catch错误链中补充信息以生成完整堆栈跟踪?
问题描述
现有如下代码:
try { try { try { throw new Error(`ERR00`) } catch (error) { throw new Error(`ERR01`) } } catch (error) { throw new Error(`ERR03`) } } catch (error) { console.log(error, (error as Error).stack); }
当前堆栈输出仅显示最外层错误,无法呈现完整错误链。若该错误链出现在func03调用func02、func02调用func01的嵌套场景中,堆栈仅会报告func03的错误,难以直接回溯问题根源。请问如何使用Error类来完善堆栈跟踪,以得到如下形式的完整错误链路输出?
Error: ERR03 at Object.<anonymous> (/[...]/test.ts:4:15) Error: ERR02 at Object.<anonymous> (/[...]/test.ts:6:15) Error: ERR01 at Object.<anonymous> (/[...]/test.ts:8:15) ....
解决方案
要保留完整错误链,核心是在抛出新错误时关联原始错误,ES2022为Error类引入的cause选项可专门用于传递错误根源,结合自定义的错误遍历打印逻辑,就能输出完整链路。
1. 使用Error的cause属性关联错误链
修改原有代码,在抛出新Error时,通过第二个参数的cause字段传入捕获到的原始错误:
try { try { try { throw new Error(`ERR00`) } catch (error) { // 关联原始错误到新错误的cause throw new Error(`ERR01`, { cause: error }) } } catch (error) { throw new Error(`ERR03`, { cause: error }) } } catch (error) { // 定义遍历错误链并打印的函数 const printErrorChain = (err: Error) => { console.log(err.stack); if (err.cause instanceof Error) { console.log('\n'); // 分隔每个错误 printErrorChain(err.cause); } }; printErrorChain(error as Error); }
2. 输出效果说明
运行修改后的代码,会逐层打印每个错误的堆栈信息,输出格式类似:
Error: ERR03 at Object.<anonymous> (/[...]/test.ts:10:15) Error: ERR01 at Object.<anonymous> (/[...]/test.ts:7:15) Error: ERR00 at Object.<anonymous> (/[...]/test.ts:4:15)
完全符合需求的完整错误链路形式,能清晰回溯每一层的错误来源。
3. 兼容旧环境的备选方案
如果运行环境不支持ES2022的cause属性,可以手动给Error实例添加自定义属性存储原始错误:
try { try { try { throw new Error(`ERR00`) } catch (error) { const newErr = new Error(`ERR01`); // 手动添加根源错误属性 (newErr as any).rootCause = error; throw newErr; } } catch (error) { const newErr = new Error(`ERR03`); (newErr as any).rootCause = error; throw newErr; } } catch (error) { const printErrorChain = (err: any) => { console.log(err.stack); if (err.rootCause instanceof Error) { console.log('\n'); printErrorChain(err.rootCause); } }; printErrorChain(error); }
这种方式也能实现相同的错误链追溯效果,仅需自行维护自定义属性即可。
内容的提问来源于stack exchange,提问作者koalaok
相关产品推荐
相关产品推荐

