You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套函数中追加新信息并重抛错误的JavaScript实现方案咨询

解决方案

方案1:基于ES2022标准的cause属性实现(推荐)

这是JavaScript原生支持的通用方案,不需要针对新增错误类型修改上层逻辑,维护成本极低。
核心思路是把原始错误作为上层错误的cause属性传入,也可以选择把原始错误的自定义属性直接合并到上层错误中,避免信息丢失:

// 改造ThirdError构造函数,支持传入原始错误作为cause
class ThirdError extends Error {
    constructor(msg, extraInfo, cause) {
        // 原生支持cause参数,会自动挂载到this.cause,低版本环境可以省略super的第二个参数手动挂载
        super(msg, { cause });
        this.arg = extraInfo;
        // 可选:把原始错误的可枚举属性直接合并到当前错误,方便直接访问
        if (cause) {
            Object.assign(this, cause);
        }
    }
}

// third函数不需要任何类型判断,新增任意错误类型都不用修改此处逻辑
function third(fn) {
    try {
        fn(25);
    } catch (error) {
        throw new ThirdError('Third error', fn, error);
    }
}

使用时可以完整拿到所有层级的错误信息:

try {
    third(first);
} catch (error) {
    console.log(error.num); // 25,直接访问原始FirstError的自定义属性
    console.log(error.cause instanceof FirstError); // true,保留原始错误类型判断
    console.log(error instanceof ThirdError); // true,上层错误类型判断也保留
    console.log(error.stack); // 堆栈信息会完整包含原始错误和上层错误的调用链路
}

方案2:直接扩展原始错误(适合需要保留原始错误类型判断的场景)

如果不需要区分错误是在哪一层抛出的,只需要追加额外信息,可以直接修改原始错误后抛出,完全保留原始错误的所有特征:

function third(fn) {
    try {
        fn(25);
    } catch (error) {
        // 直接给原始错误追加额外信息,不生成新的错误实例
        error.thirdArg = fn;
        error.message = `Third error: ${error.message}`; // 也可以追加错误消息
        throw error;
    }
}

使用时完全保留原始错误的类型判断:

try {
    third(first);
} catch (error) {
    console.log(error instanceof FirstError); // true,原始类型判断不受影响
    console.log(error.num); // 25,原有属性全部保留
    console.log(error.thirdArg); // 追加的属性可以正常访问
}

内容的提问来源于stack exchange,提问作者cj-2307

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:54:01