
FastGPT 后端错误处理检查标准从 PR 评审到源码实践的健壮错误处理指南【免费下载链接】FastGPTFastGPT is a knowledge-based platform built on the LLMs, offers a comprehensive suite of out-of-the-box capabilities such as data processing, RAG retrieval, and visual AI workflow orchestration, letting you easily develop and deploy complex question-answering systems without the need for extensive setup or configuration.项目地址: https://gitcode.com/GitHub_Trending/fa/FastGPT导读本文以 FastGPT 仓库内置的 后端错误处理检查标准 为核心骨架系统讲解后端 TypeScript 代码中四类高频错误处理缺陷的识别方法、修复范例与工程原则。该标准服务于 FastGPT 的 PR 评审流程见 pr-review Skill适用于一切涉及async/await、日志记录、业务状态码映射的后端模块开发。读完本文你将掌握异步异常兜底、错误链保留、Fire-and-Forget 防护以及业务错误与系统错误隔离的完整实战方案并能结合 FastGPT 的ERROR_ENUM错误码体系与统一日志组件写出可评审、可排障、可上线的后端代码。1. 检查标准总览评审时看什么FastGPT 的 PR 评审 Skill 将后端质量拆分为三个独立维度error-handling.md错误处理、performance.md性能、security.md安全。其中错误处理标准聚焦四个检查点按严重程度分级编号检查点严重度核心风险1异步操作未覆盖错误处理严重Promise 静默失败或未处理拒绝2错误信息丢失一般排障信息被吞掉问题难复现3Fire-and-Forget 未挂 catch严重未处理 rejection 可能击穿 Node.js 进程4业务错误与系统错误混淆一般业务失败错误地被当作 500 系统错误返回四个检查点互为补充前三个解决错误有没有被捕获、捕获后信息是否完整、异步任务是否兜底第四个解决错误以何种语义返回给调用方。下文逐一展开并在最后结合 FastGPT 源码剖析其底层错误处理基础设施。2. 检查点一异步操作未覆盖错误处理严重问题本质所有async/await操作都可能抛出异常。若在没有上层兜底的独立异步调用处省略 try-catch错误会直接向上抛出且不携带任何业务上下文导致 Promise 静默失败或出现未处理的拒绝unhandled rejection。// ❌ 无 try-catch错误向上抛出且无上下文 async function deleteUser(userId: string) { await db.users.deleteOne({ id: userId }); }修复范式// ✅ 捕获错误记录上下文重新抛出 async function deleteUser(userId: string): Promisevoid { try { const result await db.users.deleteOne({ id: userId }); if (result.deletedCount 0) { throw new Error(User not found: ${userId}); } } catch (error) { addLog.error(error, Failed to delete user: ${userId}); throw error; } }修复要点有三用try/catch包住可能失败的异步操作catch 中携带业务上下文此处为userId记录日志记录日志后重新抛出把错误交给更上层处理而不是吞掉。例外情况API 路由的顶层 handler 通常由框架统一捕获FastGPT 中即下文将分析的processError统一错误出口因此内部 service 可以直接throw不需要每层都 try-catch。评审时的重点对象是没有上层兜底的独立异步调用——例如定时任务、队列消费、事件回调、初始化脚本等入口处的裸await。3. 检查点二错误信息丢失一般问题本质catch 中创建新 Error 但不保留原始错误会让为什么失败彻底不可知空 catch 则直接静默失败属于更隐蔽的隐患。// ❌ 原始错误信息丢失 catch (error) { throw new Error(Save failed); // 为什么失败不知道 } // ❌ 空 catch静默失败 catch (error) { // 什么都不做 }修复范式保留错误链// ✅ 保留错误链 catch (error) { addLog.error(error, Save user failed); throw new Error(Save user failed: ${String(error)}, { cause: error }); }利用 ES2022 的Error构造函数第二参数{ cause: error }保留原始错误同时在新错误消息中拼接业务上下文日志与堆栈两端都不丢失信息。确需忽略时的规范并非所有错误都必须抛出。确需忽略时必须写明原因并至少降级记录 warn 日志// ✅ 确需忽略时必须写明原因 catch (error) { // 清理临时文件失败不影响主流程记录日志后忽略 addLog.warn(error, Temp file cleanup failed); }这类注释说明忽略原因 日志留痕的写法在 FastGPT 中有真实对应packages/service/core/workflow/dispatch/tools/runUpdateVar.ts中处理变量更新除零场景时即采用addLog.warn([VariableUpdate] Divide by zero, keep old value, { oldValue })的模式——保留旧值、记录警告、不中断工作流注释与日志共同交代了忽略的业务理由。4. 检查点三Fire-and-Forget 未挂 catch严重问题本质不await的 Promisefire-and-forget如果抛出错误会成为未处理的 rejection。在 Node.js 中默认行为下未处理 rejection 可能导致进程崩溃——这对常驻的 API 服务是致命的。// ❌ 错误无处捕获 sendNotification(userId); updateLastLogin(userId);修复范式// ✅ 如不需要等待至少挂 .catch sendNotification(userId).catch(err addLog.warn(err, Notification send failed, non-critical) ); // ✅ 或用 void 明确表示有意忽略需团队约定 void sendNotification(userId).catch(err addLog.warn(err, Notification failed) );两种写法都在不阻塞主流程的前提下为 Promise 提供了兜底.catch消费掉 rejectionvoid运算符向读者显式声明此处有意忽略返回值配合.catch形成明确意图 异常兜底的双保险。评审时应关注所有void、setTimeout回调、事件监听器中的异步调用是否都有.catch或内部 try-catch 兜底。5. 检查点四业务错误与系统错误混淆一般问题本质业务错误如用户不存在无权限应当以明确的业务语义返回给调用方如 4xx 状态码 业务错误码而不是被框架当作 500 系统错误。若 service 层直接throw new Error(User not found)错误消息是纯文本框架无法判断其业务属性只能落入 500。// ❌ 业务错误被当成系统错误 async function getUser(userId: string) { const user await db.users.findById(userId); if (!user) throw new Error(User not found); // 被框架捕获后返回 500 }修复范式使用 ERROR_ENUMFastGPT 对此提供了标准答案抛出定义在错误码枚举中的业务错误标识由统一错误出口将其翻译为 4xx 业务响应// ✅ 使用业务错误类FastGPT 中使用 ERROR_ENUM import { ERROR_ENUM } from fastgpt/global/common/error/errorCode; async function getUser(userId: string) { const user await db.users.findById(userId); if (!user) { throw new Error(ERROR_ENUM.unAuthUser); // 框架识别为 4xx 业务错误 } return user; }评审要点是凡是面向用户语义的业务失败不存在、无权限、超频、余额不足等一律走业务错误码不得裸抛字符串或落入 500。6. 纵深FastGPT 的错误处理基础设施上述检查标准之所以能落地依赖 FastGPT 沉淀的整套错误处理基础设施。理解它们评审才能从改对上升到改对且符合项目规范。6.1 统一错误码注册表errorCode.tspackages/global/common/error/errorCode.ts 是全部业务错误码的汇总出口ERROR_ENUM跨模块共用的高频枚举包含unAuthorization、insufficientQuota、unAuthModel、unAuthApiKey、tooManyRequest、uploadFileIntervalLimit等。例如unAuthorization映射code: 403tooManyRequest映射code: 429ERROR_RESPONSE把每个枚举值/错误标识映射为{ code, statusText, message, data, httpStatus? }的完整响应结构消息文本统一走i18nT国际化ERROR_CODEHTTP 标准状态码400/401/403/404/405/406/410/422/429/500/502/503/504的中文/多语言说明proxyError标记ECONNABORTED、ECONNRESET等代理层网络错误供上层做重试或降级判断。6.2 分模块错误码按业务域切片错误码按业务域拆分在 packages/global/common/error/code/ 下每个文件以固定的起始码段组织文件起始码示例common.ts507000invalidParams、fileNotFound、folderDepthLimituser.ts503000notUser、userExist、account_psw_error、sendVerificationCodeTooFrequentlychat.ts / dataset.ts对应业务段对话与知识库相关错误system.ts / s3.ts系统与存储段系统级与对象存储上传类错误每个文件遵循同一模式定义枚举 → 声明{ statusText, message, httpStatus? }列表 → 用reduce按起始码递增生成{ [statusText]: { code, statusText, message, data: null, httpStatus? } }。httpStatus字段是可选的显式 HTTP 状态映射如fileNotFound映射 404、验证码超频映射 429、注销中映射 403。最终这些模块级错误码通过errorCode.ts的...appErr、...userErr等展开合并进ERROR_RESPONSE单一查找表。6.3 统一错误出口processError与 HTTP 状态推导packages/service/common/response/index.ts 中的processError是 API 层的统一错误处理函数工作链路如下取error的字符串或message作为 key在ERROR_RESPONSE中查找命中则组装ProcessedError含code、statusText、message、data、httpStatus并对unAuthorization做特殊处理shouldClearCookie true触发登录态清理未命中则走兜底逻辑记录错误日志并返回默认 500。同时resolveHttpStatusForApiError实现了业务 JSON code 与 HTTP 状态码的解耦绝大多数业务码是 5xxxxx 形态不能直接当作 HTTP status函数仅将 400–499 的业务码、显式声明的 4xx–5xxhttpStatus、S3 上传校验段510000–510999映射为 400、EntityTooLarge映射为 413其余默认 500。这正是业务错误返回 4xx、系统错误返回 500的具体实现依据。配套工具位于 packages/global/common/error/utils.tsgetErrText(err, def)从任意错误对象逐级提取可读文本依次探测system_error_text、errorText、displayMessage、response.data.message、message、msg等并调用replaceSensitiveText过滤敏感信息UserErrormessage 保留业务机器码供旧调用方判断displayMessage可携带含资源名称的具体提示ToastHandledError标记错误提示已由业务侧展示通用请求层跳过重复 toast。6.4 统一日志组件getLogger/addLog检查标准中的addLog.error/addLog.warn对应 FastGPT 的统一日志体系packages/service/common/logger/index.ts 从fastgpt-sdk/otel/logger导出getLogger、withContext等。其底层实现sdk/otel/src/logger/client.ts基于logtape/logtape按LogCategory如LogCategories.HTTP.ERROR、LogCategories.MODULE.WORKFLOW.DISPATCH分类支持 console 与 OpenTelemetry 双 sink且带敏感字段过滤与结构化上下文。因此评审中要求记录日志不是可选项而是直接对接生产可观测性的事实标准。7. 综合示例与自检清单将四个检查点组合到一段真实风格的 service 代码中import { ERROR_ENUM } from fastgpt/global/common/error/errorCode; import { addLog } from /common/logger; // 1. 入口有上层兜底时可 throw2. 带上下文日志3. 业务失败用业务错误码 async function removeUserResource(userId: string): Promisevoid { try { const result await db.resources.deleteMany({ ownerId: userId }); if (result.deletedCount 0) { throw new Error(ERROR_ENUM.unAuthUser); // 业务错误不落 500 } } catch (error) { addLog.error(error, Failed to remove user resource: ${userId}); throw error; } } // 3. fire-and-forget 必须挂 .catch void notifyUser(userId).catch(err addLog.warn(err, User notify failed, non-critical) );提交 PR 前的错误处理自检清单每个无上层兜底的独立异步调用都有 try-catch 或.catchcatch 中保留了错误链{ cause: error }并携带业务上下文确需忽略的错误写明了原因并至少记录 warn所有 fire-and-forget Promise 均挂.catch必要时加void表明意图业务失败不存在/无权限/超频等使用ERROR_ENUM或对应模块错误枚举不裸抛字符串错误消息经getErrText/replaceSensitiveText清洗不泄漏敏感信息日志统一走addLog对接 OTel而非裸console。8. 结语FastGPT 的后端错误处理检查标准虽然只有四个检查点却覆盖了错误从产生到传播到呈现的完整链路try-catch 兜底解决捕获问题错误链保留解决排障问题.catch挂载解决异步泄漏问题ERROR_ENUM隔离解决语义问题。在 FastGPT 中这些规范由 errorCode.ts 的错误码注册表、response/index.ts 的统一出口与 logger 的观测体系共同支撑形成了从编码规范到运行时行为的一致闭环。评审者与开发者均可直接以该标准为纲对照仓库源码逐项落实。【免费下载链接】FastGPTFastGPT is a knowledge-based platform built on the LLMs, offers a comprehensive suite of out-of-the-box capabilities such as data processing, RAG retrieval, and visual AI workflow orchestration, letting you easily develop and deploy complex question-answering systems without the need for extensive setup or configuration.项目地址: https://gitcode.com/GitHub_Trending/fa/FastGPT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考