自定义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
相关产品推荐
相关产品推荐

