如何正确捕获JavaScript/TypeScript错误并为其附加额外信息
解决方案
方案1:使用ES2022原生cause属性(推荐)
ES2022标准已经为Error构造函数新增了第二个可选的options参数,其中的cause字段就是用来存放原始错误的,和你提到的Java、PHP的previous参数作用完全一致。
示例代码:
try { // 可能抛出错误的代码 } catch (e) { throw new Error(`Error while processing file ${path}`, { cause: e }); }
之后如果要获取原始错误,直接访问新错误的.cause属性即可,原始错误的栈信息、自定义属性都会完整保留。
该特性在Node.js 16.9.0+、所有现代浏览器中都已原生支持,TypeScript 4.6+也内置了对应的类型支持。
方案2:自定义包装错误类(兼容旧环境/自定义扩展)
如果需要兼容低于ES2022的运行环境,或者需要给错误附加更多自定义逻辑,可以自己实现支持原因参数的错误类:
// TypeScript 实现 class WrappedError extends Error { public readonly cause?: Error; // 可以自定义扩展其他需要的字段 public readonly filePath?: string; constructor(message: string, options?: { cause?: Error, filePath?: string }) { super(message); // 修复原型链,确保instanceof判断正常 Object.setPrototypeOf(this, WrappedError.prototype); this.name = this.constructor.name; this.cause = options?.cause; this.filePath = options?.filePath; // 可选:自动拼接栈信息,打印时直接能看到原始错误栈 if (this.cause?.stack) { this.stack = `${this.stack}\nCaused by: ${this.cause.stack}`; } } }
使用示例:
try { // 可能抛出错误的代码 } catch (e) { throw new WrappedError(`Error while processing file ${path}`, { cause: e as Error, filePath: path }); }
方案3:直接给原始错误附加自定义属性
如果不需要修改错误提示信息,只是要附加额外上下文信息,可以直接给捕获到的原始错误挂载属性:
try { // 可能抛出错误的代码 } catch (e) { if (e instanceof Error) { // 附加自定义字段 (e as any).filePath = path; (e as any).operator = currentUserId; } throw e; }
内容的提问来源于stack exchange,提问作者Nemo64
相关产品推荐
相关产品推荐

