NestJS 中 instanceof 检查失效导致异常处理错误

news/2026/1/23 17:08:54/文章来源:https://www.cnblogs.com/dingtongya/p/19523287

NestJS 中 instanceof 检查失效导致异常处理错误

问题描述

在 NestJS 微服务项目中,使用全局异常过滤器 HttpExceptionFilter 捕获异常时,发现 UnauthorizedException 虽然继承自 HttpException,但 instanceof 检查返回 false,导致异常被误判为未知异常,返回错误的错误码。

现象

期望行为

{"success": false,"data": null,"errorCode": 1002,"errorMessage": "无效的令牌"
}

实际行为

{"success": false,"data": null,"errorCode": 1000,"errorMessage": "Unauthorized"
}

调试发现

通过调试发现以下异常特征:

  1. 异常对象的 [[Prototype]] 正确显示为 HttpException
  2. exception.name"UnauthorizedException"
  3. exception instanceof HttpException 返回 false

根本原因

模块实例化问题

在 Monorepo 或多模块项目中,@nestjs/common 被多次实例化,导致不同模块中的类引用不一致。

// api-gateway 模块中的 HttpException
const HttpException_A = require('@nestjs/common').HttpException;// shared-config 模块中的 HttpException
const HttpException_B = require('@nestjs/common').HttpException;// 虽然是同一个包,但是不同的实例
HttpException_A !== HttpException_B; // true// UnauthorizedException 继承自 HttpException_A
const ex = new UnauthorizedException();// 在 shared-config 中检查
ex instanceof HttpException_B; // false ❌

instanceof 的工作原理

obj instanceof Constructor
// 等价于
Constructor.prototype.isPrototypeOf(obj)

instanceof 检查依赖于构造函数的引用相等性,当构造函数来自不同模块实例时,检查会失败。

技术背景

项目结构

  • api-gateway: API 网关服务
  • main-service: 主服务(用户服务)
  • other-service: 其他服务(通知服务)
  • shared-config: 共享配置包(本地包)
  • web: 前端应用

依赖关系

api-gateway└── @nest-m/shared-config (本地包)shared-config└── @nestjs/commonapi-gateway└── @nestjs/common

这导致 @nestjs/common 在两个不同的上下文中被加载。

解决方案

方案 1:使用 name 属性检查(推荐)

不依赖 instanceof,而是检查异常的 name 属性:

// 处理 instanceof 失败但实际是 HttpException 的情况
else if (exception instanceof Error &&['UnauthorizedException', 'BadRequestException', 'NotFoundException','ForbiddenException', 'ConflictException'].includes(exception.name)
) {const exceptionObj = exception as any;status = exceptionObj.getStatus ? exceptionObj.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;errorCode = this.getErrorCodeFromStatus(status);errorMessage = exception.message;this.logger.error(`[${errorCode}] ${errorMessage}`,`${request.method} ${request.url}`,);
}

优点

  • ✅ 不依赖 instanceof
  • ✅ 不受模块实例化问题影响
  • ✅ 性能更好
  • ✅ 代码更清晰

方案 2:检查原型链

else if (exception instanceof Error) {const httpException = require('@nestjs/common').HttpException;if (httpException.prototype.isPrototypeOf(exception)) {status = exception.getStatus();errorCode = this.getErrorCodeFromStatus(status);errorMessage = exception.message;}
}

优点

  • ✅ 检查原型链,更准确
  • ✅ 不依赖构造函数引用

缺点

  • ❌ 仍需动态导入
  • ❌ 代码稍复杂

方案 3:统一依赖版本(治本)

确保所有服务使用相同版本的 @nestjs/common

# 使用 npm workspaces
npm workspaces# 或使用 pnpm workspace
pnpm workspace# 或在根目录的 package.json 中统一管理
{"workspaces": ["api-gateway","main-service","other-service","shared-config"]
}

优点

  • ✅ 治本方案
  • ✅ 避免依赖重复

缺点

  • ❌ 需要重构项目结构
  • ❌ 可能影响现有构建流程

经验教训

1. Monorepo 中的模块实例化问题

在 Monorepo 项目中,共享包可能导致依赖被多次实例化,需要特别注意类的引用一致性。

2. instanceof 的局限性

instanceof 依赖于构造函数的引用相等性,在模块化环境中可能不可靠,尤其是在以下场景:

  • Monorepo 项目
  • 使用本地共享包
  • 微服务架构
  • Webpack 打包

3. 防御性编程

在异常处理中使用多种检查方式,避免单点失效:

// 组合多种检查方式
if (exception instanceof HttpException) {// 方式1: instanceof
} else if (exception instanceof Error &&['UnauthorizedException'].includes(exception.name)
) {// 方式2: name 属性
} else if (exception instanceof Error &&HttpException.prototype.isPrototypeOf(exception)
) {// 方式3: 原型链
}

4. 调试技巧

使用 Object.getPrototypeOf() 检查原型链,比 instanceof 更可靠:

const proto = Object.getPrototypeOf(exception);
console.log('Prototype:', proto?.constructor?.name);
console.log('Is HttpException?', HttpException.prototype.isPrototypeOf(exception));

适用场景

  • ✅ NestJS Monorepo 项目
  • ✅ 使用本地共享包(shared-config)
  • ✅ 微服务架构
  • ✅ 需要统一异常处理的场景
  • ✅ 使用 Webpack 或其他打包工具的项目

相关资源

  • NestJS Exception Filters
  • JavaScript instanceof MDN
  • Monorepo 最佳实践

总结:在模块化项目中,instanceof 检查可能因为模块实例化问题而失效。使用 name 属性或原型链检查是更可靠的替代方案。在生产环境中,建议使用组合检查方式,确保异常处理的健壮性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1205836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

06-Example目录下,有好多例子可以加强学习

06-Example目录下,有好多例子可以加强学习Viwer目录下,PDF缩放,文本查找,标签显示

完整教程:RGB 色彩比例(R/(R+G+B)、G/(R+G+B)、B/(R+G+B))的核心含义与应用

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

泵站选购指南2026:泵站联系方式解析品质之选,雨水提升泵站/钢丝绳牵引格栅/沉水转鼓微滤机,泵站生产厂家口碑推荐

在市政建设、工业生产和环境治理领域,泵站作为流体输送与提升的核心枢纽,其运行稳定性直接关系到供水安全、排水效率及污水处理效果。尤其随着“新基建”与智慧水务的推进,市场对高性能、高可靠性、智能化泵站的需求…

2026年国内知名的CTU货架生产厂家哪个好,可调节货架/背网货架/货架/不锈钢货架,CTU货架生产厂家推荐榜单

随着仓储物流行业自动化升级加速,CTU(Carrier Transport Unit)货架作为智能仓储的核心载体,其技术适配性与系统集成能力成为企业采购决策的关键。本文基于公开市场数据、行业调研及企业公开信息,筛选出5家具有代表…

2025年度苏州牙周治疗机构权威榜单出炉,口碑之选,儿童牙齿正畸/老人牙齿修复/牙齿种植/修复牙齿,牙周治疗机构哪家好

随着国民健康意识的提升,口腔健康,尤其是牙周健康,正受到前所未有的关注。牙周病作为最常见的口腔疾病之一,不仅是成年人牙齿丧失的首要原因,更与全身系统性疾病存在密切关联。在苏州这座经济发达、医疗资源丰富的…

示例代码解析:使用 item_get_video_pro 获取小红书笔记详情

一、功能介绍 item_get_video_pro 是一个用于获取小红书(Xiaohongshu)笔记详情的接口,支持获取包括标题、描述、点赞数、评论数、封面图、视频链接等在内的完整笔记信息。该接口适用于内容分析、数据抓取、社交媒体…

Java计算机毕设之基于Web的智能选择系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026 年 APP / 小程序开发服务商精选:昊客网络聚焦核心技术,铸就行业翘楚

2026年,中国数字化进程已从“有没有系统”迈入“系统是否真正驱动业务”的新阶段。据艾瑞咨询最新报告,超73%的企业在选择软件开发服务商时,将“落地效果”和“技术可控性”置于价格之上。然而,当前市场仍存在明显…

2026西安大型激光切管机厂家优选指南——本地化服务标杆企业推荐

随着激光加工技术在智能制造领域的深度渗透,西安作为西北制造业核心城市,对高精度、大规模激光切管服务的需求持续攀升。2024年中国激光加工设备行业市场规模已达899亿元,其中激光切割设备占比超39%,成为推动行业增…

技术面:如何让你的系统抗住高并发的流量?

高并发架构设计无外乎“拆、缓、防”三板斧:先通过业务分治、数据分片、集群化部署把系统横向扩展到极致;再以多级缓存与消息队列将瞬时峰值削平成可线性增长的消息流;最后用限流、熔断、降级以及异地多活等多维防护…

上海高精度管道喷涂机设备批发价格大揭秘,谁更实惠?

本榜单依托全维度市场调研与真实行业口碑,深度筛选出五家管道防腐修复设备及服务领域的标杆企业,为市政工程、工业企业、工程承包单位选型提供客观依据,助力精准匹配适配的合作伙伴。 TOP1 推荐:上海蓝云管道工程有…

漂粉精过滤机公司哪家性价比高

随着工业生产对分离设备精度、效率要求的不断提升,漂粉精过滤机、盐过滤机、碱过滤机等专用分离设备的选型逐渐成为化工、环保等行业企业的核心痛点——选对设备能大幅提升生产效率、降低运营成本,选错则可能导致物料…

探寻售后完善的脱发治疗中医企业,天津市道医实力出众

在当代快节奏生活中,脱发已成为困扰无数人的健康难题。从熬夜加班的职场人到备考压力大的学生,从产后妈妈到中年群体,脱发问题不仅影响外在形象,更可能打击自信心,引发焦虑情绪。面对市场上五花八门的脱发治疗方案…

想了解养老院怎么联系?惠州祥和养老院别错过

在老龄化程度不断加深的当下,选择一家口碑好、服务优的养老院,是许多家庭为长辈安享晚年的重要课题。面对市场上良莠不齐的养老机构,如何找到真正能让老人舒心、家属放心的选择?以下结合不同服务类型,为你梳理惠州…

2026年超高分子量聚乙烯板靠谱供应商Top10,山峰塑化强势入围!

本榜单依托全维度市场调研与真实工业领域口碑,深度筛选出五家超高分子量聚乙烯板领域的标杆企业,聚焦工业客户耐磨抗粘结、成本可控、服务高效的核心需求,为企业选型提供客观依据,助力精准匹配适配的材料供应伙伴。…

职场人职业规划 PPT 生成,简约商务模板一键套用

我的职业规划PPT生成秘籍:6款神器助你轻松搞定职场展示 作为一位在PPT行业摸爬滚打五年的内容创作者,我经历过无数次熬夜改PPT的崩溃时刻——尤其是当需要制作职业规划PPT时,既要展现专业度又要突出个人特色,简直像在走钢丝。直到…

Java毕设选题推荐:基于JavaWeb的智能生活选择系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

防关联浏览器有用吗?哪家防关联浏览器好用?

防关联浏览器大家有听说过吗?在跨境电商行业里面,大家对防关联应该感觉到不陌生,那么防关联浏览器有用吗?哪家防关联浏览器好?对于防关联浏览器,下面就来详细的做个分析。 防关联浏览器有用吗? 其实很好理解,防…

2026年求推荐龙飞云平台,口碑好的公司排名揭晓!

本榜单依托全维度市场调研与真实行业口碑,深度筛选出五家标杆企业,为中小企业数字化转型提供客观依据,助力精准匹配适配的服务伙伴。 TOP1 推荐:龙飞云 推荐指数:★★★★★ | 口碑评分:京津冀区域靠谱的AI搜索优…

秋冬季特别补水的身体乳哪个品牌好?2026秋冬保湿身体乳横评,长效锁水续航

秋冬干燥季,身体乳的“锁水续航力”直接决定肌肤状态。为了找出真正能对抗干燥、兼顾肤感与功效的产品,我们以“72小时锁水率、吸收速度、成分安全性、修护力”为核心测评维度,对20余款热门身体乳进行盲测,最终筛选…