ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Egg 框架常见错误排查指南:TEGG_EGG_PROTO_NOT_FOUND 与 TEGG_ROUTER_CONFLICT 深度解析

Egg 框架常见错误排查指南:TEGG_EGG_PROTO_NOT_FOUND 与 TEGG_ROUTER_CONFLICT 深度解析 后端Web框架【免费下载链接】egg Born to build better enterprise frameworks and apps with Node.js Koa. https://307.run/eggcode项目地址https://gitcode.com/gh_mirrors/eg/egg点击查看免费下载导读本文以 Eggtegg框架官方 FAQ 文档site/docs/faq/index.md中收录的两类高频运行期错误为线索逐一拆解TEGG_EGG_PROTO_NOT_FOUND依赖注入失败与TEGG_ROUTER_CONFLICT路由冲突的报错现象、源码级根因与完整修复方案。读完本文你将掌握 Egg Module 依赖注入的查找链路Proto 注册、AccessLevel 访问级别、Load Unit 作用域以及 HTTP 路由注册时的去重校验机制能够独立定位并修复这两类在 tegg 工程中极易踩坑的问题。一、错误总览两个 FAQ 条目背后的统一错误体系Eggtegg框架内置了一套结构化的错误分类体系。FAQ 中收录的每个错误都拥有独立文档分别描述Problem现象— Cause根因— Solution解决方案— Example示例四个环节FAQ 条目错误类名错误码触发场景TEGG_EGG_PROTO_NOT_FOUNDEggPrototypeNotFoundEGG_PROTO_NOT_FOUND依赖注入时找不到目标 ProtoTEGG_ROUTER_CONFLICTRouterConflictErrorROUTER_CONFLICTHTTP 路由注册时发现重复规则从源码看这两类错误都继承自 tegg 的框架基础错误。在 tegg/core/metadata/src/errors.ts 中TeggError继承FrameworkBaseError并将模块标记为TEGGEggPrototypeNotFound依据是否携带loadUnitId生成Object ${name} not found in ${loadUnitId}或Object ${name} not found两种消息而 tegg/core/controller-runtime/src/lib/errors.ts 中的RouterConflictError同样继承TeggError。因此你看到的报错前缀framework.正是这一统一错误体系的体现。二、TEGG_EGG_PROTO_NOT_FOUND依赖注入目标缺失2.1 错误现象当注入器在当前 Egg Module 中找不到目标对象时应用启动或运行期会抛出如下异常framework.EggPrototypeNotFound: Object foo not found in LOAD_UNIT:appPort其中foo是待注入对象的Proto 名称LOAD_UNIT:appPort是当前**加载单元Load Unit**的 ID它标明了从哪里找不到。2.2 根因Proto 查找链路全解析该错误在注入解析阶段抛出。结合源码可以还原完整的查找链路查找入口InjectObjectPrototypeFinder.findInjectObjectPrototypes 遍历目标 Proto 的所有注入对象injectObjects对每个注入对象调用findInjectObjectPrototype依次尝试默认、Context、自身上下文三种查找策略。工厂解析EggPrototypeFactory.getPrototype 按name loadUnit qualifiers解析 Proto当doGetPrototype返回空数组时即抛出EggPrototypeNotFound。两层命中规则doGetPrototype先查当前 Load Unit 内的私有 ProtoloadUnit.getEggPrototype未命中再查全局的 PUBLIC Proto 表publicProtoMap见 EggPrototypeFactory.ts。可选注入兜底若注入对象标记为optionalEggPrototypeNotFound会被吞掉继续后续注入见 InjectObjectPrototypeFinder.ts非可选注入则直接抛错即你看到的TEGG_EGG_PROTO_NOT_FOUND。也就是说凡是导致在当前 Load Unit 私有表 全局 PUBLIC 表中都查不到匹配 Proto的情况都会触发此错误。2.3 关键概念AccessLevel 访问级别命中全局 PUBLIC 表的前提是 Proto 的访问级别为AccessLevel.PUBLIC。在 tegg/core/types/src/core-decorator/enum/AccessLevel.ts 中定义了两个取值export const AccessLevel { // only access from self load unit PRIVATE: PRIVATE, // can access from parent load unit PUBLIC: PUBLIC, } as const;PRIVATE仅可从自身 Load Unit内访问不会被注册进全局 PUBLIC 表PUBLIC可从父 Load Unit及全局范围内访问注册时会被放入publicProtoMap对应 EggPrototypeFactory.registerPrototype 中if (proto.accessLevel AccessLevel.PUBLIC)分支。排查要点当你尝试跨 Module 注入一个PRIVATE的 Proto或目标 Module 内的 Proto 忘了标注PUBLIC全局表里自然查不到错误随之而来。2.4 七步排查清单对照 FAQ 文档TEGG_EGG_PROTO_NOT_FOUND.md给出的标准排查顺序确认 Proto 已定义当前 Module 中确实声明了对应装饰器如SingletonProto、ContextProto、MultiInstanceProto且文件被正确加载。确认访问级别Proto 的accessLevel设为AccessLevel.PUBLIC跨 Module 注入时尤其关键。确认 Proto 名称正确注入处引用的名称与定义处的名称类名或自定义name完全一致注意大小写。确认实例化方式正确注入端与提供端使用的ObjectInitType如SINGLETON/CONTEXT匹配。确认实例化名称正确装饰器选项中name字段拼写无误。确认实例化访问级别正确实例化入口如工厂方法的访问级别符合调用方需求。确认实例化实例名称正确若存在多个实例instanceName/qualifier 需与注入端声明的限定符一致。2.5 修复示例FAQ 提供的标准修复模板如下来自 TEGG_EGG_PROTO_NOT_FOUND.mdimport { SingletonProto, AccessLevel } from egg; SingletonProto({ // Ensure the Protos access level is PUBLIC accessLevel: AccessLevel.PUBLIC, // [!code focus] }) export class Foo { async bar(): Promisestring { return bar; } }修复时只需聚焦两个动作在定义处补上accessLevel: AccessLevel.PUBLIC并在注入处核对名称与限定符。若错误信息中的LOAD_UNIT明确指向某个特定模块优先回到该模块检查上述 1、2、3 三项。三、TEGG_ROUTER_CONFLICTHTTP 路由规则冲突3.1 错误现象当两个 Controller 注册了完全相同的 HTTP 方法 路径规则时会抛出framework.RouterConflictError: register http controller GET AppController2.get failed, GET /apps/:id is conflict with exists rule /apps/:id消息格式为register http controller METHOD Controller.method failed, METHOD path is conflict with exists rule path其中path是拼接后的真实路径real path。3.2 根因路由注册时的去重校验路由冲突发生在 HTTP 方法注册阶段。在 HTTPMethodRegister.checkDuplicate 中每次注册前都会执行两步重复检查宿主路由检查对主router调用checkDuplicateInRoutertegg 控制器路由检查对checkRouters中按 host 隔离的临时路由做同样的校验。checkDuplicateInRouterHTTPMethodRegister.ts的关键逻辑是用router.match(methodRealPath, method)判断同 HTTP 方法 同路径规则是否已存在private checkDuplicateInRouter(router: Router) { const methodRealPath this.controllerMeta.getMethodRealPath(this.methodMeta); const matched router.match(methodRealPath, this.methodMeta.method); const methodName this.controllerMeta.getMethodName(this.methodMeta); if (matched.route) { const [layer] matched.path; const err new RouterConflictError( register http controller ${methodName} failed, ${this.methodMeta.method} ${methodRealPath} is conflict with exists rule ${layer.path}, ); throw FrameworkErrorFormater.format(err); } }注意两点实现细节真实路径是拼接产物getMethodRealPath通过path.posix.join(controller.path, method.path)拼接控制器前缀与方法路径见 HTTPControllerMeta.ts。因此冲突判断的是拼接后的完整路径而非单个装饰器里的片段。区分大小写与参数占位匹配基于path-to-regexp规则register中构造正则时设置了sensitive: true/apps/:id与/apps/:pid这类参数名不同但形态相同的规则同样视为冲突。3.3 排查与修复FAQ 给出的解决要点有两条确保路由规则唯一同一 HTTP 方法下真实路径不得重复确保路由规则正确检查控制器前缀Controller与方法路径Get等的拼接结果是否符合预期。FAQ 的复现场景是AppController与AppController2同时定义了/apps/:idTEGG_ROUTER_CONFLICT.mdController(/apps) // [!code focus] export class AppController { Get(/:id) // [!code focus] async get(Param(id) id: string) { return this.app.apps.get(id); } }Controller(/apps) // [!code focus] export class AppController2 { Get(/:id) // [!code focus] async get(Param(id) id: string) { return this.app.apps.get(id); } }修复方向结合源码推断的实际操作修改其中一个控制器的Controller前缀例如将AppController2改为Controller(/admin/apps)或修改方法级路径装饰器将其中一个改为Get(/:appId)之外的独立规则或直接删除重复定义保留唯一实现。3.4 最佳实践如何从源头避免冲突统一规划路径前缀按业务域如/admin、/api、/apps划分控制器前缀避免多个 Controller 共用相同前缀下相同形态的路径。善用路径参数命名差异明确/apps/:id与/apps/list、/apps/:appId这类规则的形态边界避免看似不同实则同形的规则并存。利用 host 隔离checkRouters按 host 隔离重复校验多 host 场景下同一路径可在不同 host 各自注册见 HTTPMethodRegister.ts但同一 host 内仍必须唯一。结合测试验证tegg 路由测试覆盖了 HTTP 方法注册与冲突检测路径参见 tegg/plugin/controller/test/lib/HTTPMethodRegister.test.ts可在 CI 中通过测试用例提前拦截重复路由。四、总结TEGG_EGG_PROTO_NOT_FOUND与TEGG_ROUTER_CONFLICT分别对应 Eggtegg依赖注入与路由注册两个核心链路的常见故障注入失败的本质是 Proto 查找不到核心控制点在AccessLevel 访问级别PUBLIC/PRIVATE与Load Unit 作用域按七步清单核对定义、名称、级别与限定符即可修复路由冲突的本质是HTTP 方法 真实拼接路径重复核心控制点在Controller前缀与方法路径的组合唯一性检查并调整前缀或路径即可。两者均继承自统一的TeggError错误体系报错前缀framework.与错误码EGG_PROTO_NOT_FOUND/ROUTER_CONFLICT可以帮助你在日志与监控中快速归类问题。更多细节可继续查阅 FAQ 原文 TEGG_EGG_PROTO_NOT_FOUND 与 TEGG_ROUTER_CONFLICT。赞分享后端Web框架【免费下载链接】egg Born to build better enterprise frameworks and apps with Node.js Koa. https://307.run/eggcode项目地址https://gitcode.com/gh_mirrors/eg/egg点击查看免费下载相关推荐Egg 框架 TEGG_EGG_PROTO_NOT_FOUND 注入失败错误排查与修复指南Egg 框架 TEGG_EGG_PROTO_NOT_FOUND 注入失败错误排查与修复指南 导读 TEGG_EGG_PROTO_NOT_FOUND 是 Egg后端Web框架TEGG_ROUTER_CONFLICT 路由冲突错误排查与修复指南tegg / egg 框架TEGG_ROUTER_CONFLICT 路由冲突错误排查与修复指南tegg / egg 框架 TEGG_ROUTER_CONFLICT 是 tegg 框架后端Web框架Egg 框架开发实战常见问题排查与 FAQ 深度解析Egg 框架开发实战常见问题排查与 FAQ 深度解析 导读本文以 Egg 官方社区 FAQ 为主线围绕问题反馈方式、配置不生效、日志去向、进程管理选型、后端Web框架上一篇CANN/cannbot-skills: Ascend C算子卡死/崩溃调试下一篇Memtest86完全指南如何用这款开源工具彻底检测内存故障创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表