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

自定义BookingError类在try/catch中instanceof校验失效问题

自定义BookingError异常的instanceof校验失效问题

我创建了一个名为BookingError的自定义异常类,用于处理所有预订相关错误,代码如下:

class BookingError extends Error{
    constructor(message: string){
        super(message);
        this.name = "BookingError";
    }
}

但抛出该异常时,无法通过instanceof可靠校验这个错误类以进行后续处理。测试代码如下:

const throwError = () => {
    throw new BookingError("This is a test.");
};

const testErrorException = () => {
    try{
        throwError();
    } catch(err: unknown){
        // 此处始终输出false
        console.log(err instanceof BookingError);
    }
};

运行上述代码后,控制台输出:

Error [BookingError]: This is a test.
同时err instanceof BookingError的结果始终为false。

有意思的是,通过检查name属性的取巧方式可以实现预期的判断效果:

if((err as BookingError).name === "BookingError"){
    // 此处将输出"This is a test."
    console.log((err as BookingError).message);
}

问题原因

在JavaScript/TypeScript中,继承Error类时,Error的构造函数会返回一个新对象,导致子类实例的原型链被意外修改,进而使instanceof校验失效。

解决方法

方法1:手动修正原型链

在BookingError的构造函数中添加原型链修正代码,确保实例的原型指向子类原型:

class BookingError extends Error{
    constructor(message: string){
        super(message);
        this.name = "BookingError";
        // 修正原型链,让instanceof正常工作
        Object.setPrototypeOf(this, BookingError.prototype);
    }
}

方法2:配置TypeScript编译目标为ES6+

如果使用TypeScript,在tsconfig.json中将target设置为ES6或更高版本,编译器会自动处理Error类的继承逻辑,无需手动修正原型链:

{
  "compilerOptions": {
    "target": "ES6"
  }
}

关于取巧方法的说明

通过name属性判断错误类型虽然能临时解决问题,但可靠性不如instanceof——如果有其他错误类也设置了相同的name值,就会出现判断错误。优先推荐上述两种标准解决方法。

内容的提问来源于stack exchange,提问作者Grover

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:37:51