TypeScript自定义CustomError在React组件catch中instanceof判断为false问题
问题原因分析
- 场景1:自定义错误从后端服务跨HTTP传输到前端
HTTP协议仅支持传输序列化的JSON数据,无法直接传递JavaScript类实例。后端抛出的CustomError在返回前端时会被序列化为普通JSON对象,前端axios接收到响应后会将其封装为内置的AxiosError实例,完全丢失了原自定义错误的原型链,因此instanceof判断返回false。 - 场景2:错误抛出逻辑和捕获逻辑在同一个前端项目
- 类定义存在多份副本:如果项目打包后
CustomError类被拆分为多个独立chunk,或者导入路径不一致导致加载了多份CustomError类定义,instanceof判断依赖的原型对象引用不相等,就会返回false。 - TypeScript编译配置问题:如果TS编译目标设置为
ES5及更低版本,内置类(Error、Array等)的继承存在原生缺陷,即使手动设置了Object.setPrototypeOf,如果不同代码块的编译配置不一致,也可能导致原型链断裂。 - axios错误被二次封装:如果在axios的请求/响应拦截器中对错误做了处理后重新抛出,要确认重新抛出的是你构造的
CustomError实例,而不是普通Error或axios原生的AxiosError。
- 类定义存在多份副本:如果项目打包后
解决方案
- 跨传输场景直接判断错误标识:不需要依赖
instanceof,可通过判断error.name === 'CustomError',或者在自定义错误中新增唯一标识字段,比如构造函数中添加this.code = 'CUSTOM_ERROR',捕获时直接判断对应字段即可。 - 同项目多副本问题:统一项目内
CustomError的导入路径,确保全局只有一份类定义,或者给类添加静态判断方法:
export class CustomError extends Error{ constructor(message: string) { super(message); Object.setPrototypeOf(this, CustomError.prototype); this.name = "CustomError"; } static is(error: unknown): error is CustomError { return error instanceof Error && error.name === 'CustomError' } }
捕获时直接使用CustomError.is(error)做判断即可,完全规避原型引用不一致的问题。
- 编译配置问题:将TS的编译目标
target调整为ES6及以上版本,可解决内置类继承的原型链问题。
内容的提问来源于stack exchange,提问作者klijakub
相关产品推荐
相关产品推荐

