
文档教程后端【免费下载链接】nodebestpractices✅ The Node.js best practices list (July 2026)项目地址https://gitcode.com/GitHub_Trending/no/nodebestpractices点击查看免费下载本指南对应 nodebestpractices 仓库错误处理实践 2.2「Extend the built-in Error object」主题是无论同步函数、EventEmitter、Promise 还是回调都以 Node.js 内置Error对象作为唯一错误载体并在此基础上派生出统一的AppError应用错误类型。读完本文你将掌握三种抛错场景的正确写法、识别抛字符串等反模式并能用一套带上下文属性错误名、HTTP 状态码、是否可预期的AppError统一全应用错误结构为集中式错误处理与操作型错误判定打下基础。为什么必须只使用内置 Error 对象JavaScript 的宽容天性加上其丰富的代码流选项EventEmitter、Callback、Promise 等导致开发者抛错的方式千差万别——有人抛字符串有人自定义五花八门的类型。仓库文档 useonlythebuiltinerror.md 给出的核心理由是保持统一性统一使用内置Error对象能让你的代码与第三方库之间的错误形态一致模块间互操作不再需要猜这次抛的是什么类型保留关键信息Error对象携带stack trace堆栈跟踪这是排查问题的核心线索承载上下文抛异常时通常应附带额外上下文属性如错误名称name和关联的 HTTP 状态码让下游调用方与日志系统能精确理解错误含义。这一点在 README.md 的 2.2 小节 TL;DR 中有更直白的表述有些库把错误抛成字符串或自定义类型这会让错误处理逻辑和模块间互操作变得复杂正确做法是创建一个从内置Error派生的应用错误对象/类在reject、throw或emit错误时统一使用它并为其添加有意义的命令式属性如错误名/错误码与isCatastrophic标志。正确做法在所有代码流中抛出 Error无论代码是同步、异步还是基于事件或 Promise错误都必须以new Error(...)的形式抛出巴西葡萄牙语原版文档 useonlythebuiltinerror.brazilian-portuguese.md 的原始示例// 从典型函数抛出 Error无论是同步还是异步 if(!productToAdd) throw new Error(Como posso adicionar um novo produto quando nenhum valor é fornecido?); // 从 EventEmitter 抛出 Error const myEmitter new MyEmitter(); myEmitter.emit(error, new Error(whoops!)); // 从 Promise 抛出 Error const addProduct async (productToAdd) { try { const existingProduct await DAL.getProduct(productToAdd.id); if (existingProduct ! null) { throw new Error(O produto já existe!); } } catch (err) { // ... } }三个场景各自对应一种典型代码流普通函数同步/异步直接throw new Error(...)由调用方通过try/catch或 Promise 链捕获EventEmitter通过emit(error, new Error(...))触发error事件。Node.js 的事件机制对error事件有特殊语义——未监听error事件的 EventEmitter 抛出错误会直接导致进程崩溃因此务必为发射器注册error监听这也是仓库 2.13「Subscribe to event emitters error event」实践的内容Promise/async 函数在async函数内throw等价于reject且会保留完整的异步堆栈上下文配合 2.12「Always await promises before returning」实践可避免堆栈截断。反模式抛出字符串没有任何堆栈信息许多开发者图省事直接throw一个字符串// 抛出字符串缺少 stack trace 信息及其他重要数据属性 if(!productToAdd) throw (Como posso adicionar um novo produto quando nenhum valor é fornecido?);这是典型的反模式。字符串不是对象不具备stack、name、message等属性抛错后你完全无法得知错误发生的代码位置同时它破坏了模块间契约——任何基于instanceof Error判断的 API包括框架的错误中间件都会将其漏判。在 README.md 的 Otherwise 部分仓库明确警告调用组件时无法确定返回的错误类型会让正确的错误处理变得困难而用自定义类型描述错误甚至可能导致堆栈跟踪这类关键错误信息丢失。更进一步从 Error 派生统一 AppError仅用裸Error还不够——为了附加错误名、HTTP 状态码、是否可预期等上下文应在全应用范围内只扩展一次内置Error得到一个集中式的AppError然后用参数区分不同错误类别而不是为每种错误DbError、HttpError……各写一个子类。仓库同时给出了 JavaScript 与 TypeScript 两种实现。JavaScript 实现原型链方式// 从 Node 的 Error 派生的集中式错误对象 function AppError(name, httpCode, description, isOperational) { Error.call(this); Error.captureStackTrace(this); this.name name; // ...其他属性在此赋值 }; AppError.prototype Object.create(Error.prototype); AppError.prototype.constructor AppError; module.exports.AppError AppError; // 客户端抛出异常 if(user null) throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, mais explicações, true)关键点在于Error.call(this)初始化错误基态Error.captureStackTrace(this)在构造调用点捕获堆栈把自身构造函数从堆栈中剥离保证堆栈指向真正的抛错现场最后通过Object.create(Error.prototype)修复原型链使instanceof Error成立。TypeScript 实现class 继承方式// 从 Node 的 Error 派生的集中式错误对象 export class AppError extends Error { public readonly name: string; public readonly httpCode: HttpCode; public readonly isOperational: boolean; constructor(name: string, httpCode: HttpCode, description: string, isOperational: boolean) { super(description); Object.setPrototypeOf(this, new.target.prototype); // 恢复原型链 this.name name; this.httpCode httpCode; this.isOperational isOperational; Error.captureStackTrace(this); } } // 客户端抛出异常 if(user null) throw new AppError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, further explanation, true)TypeScript 中有一个极易踩的坑Error的子类编译为 ES5 目标时实例的__proto__可能被错误覆盖导致instanceof Error为false。解法是构造函数中调用Object.setPrototypeOf(this, new.target.prototype)恢复原型链——这也是仓库原文档特别标注new.target支持的原因。AppError 与相邻实践的协同AppError构造函数的第四个参数isOperational并非摆设它直接衔接仓库的 2.3「区分操作型错误与程序员错误」实践见 operationalvsprogrammererror.mdisOperational为true表示错误可预期、影响可控如输入校验失败、外部服务连接失败只需记录日志即可为false则属于程序员错误如读取未定义值、内存泄漏应用可能已处于不一致状态应当优雅退出并由进程守护工具如 Docker、PM2重启。在集中式错误处理器中见 centralizedhandling.md 的handleError示例正是依据该标志决定发送错误响应还是崩溃进程// 集中式错误处理器依据 isOperational 决策 this.handleError async (error, responseStream) { await logger.logError(error); await fireMonitoringMetric(error); await crashIfUntrustedErrorOrSendResponse(error, responseStream); };因此仅使用内置Error 单一AppError派生是整条错误处理链统一结构 → 操作型判定 → 集中处理 → 优雅退出的第一环。用 ESLint 规则强制约束仓库 README.md 还建议通过 ESLint 从机制上杜绝抛字符串内置规则no-throw-literal会严格检查不允许throw字面量字符串/数字等它虽存在一定局限对部分动态表达式无法静态判定但在 TypeScript 项目中开启typescript-eslint/no-throw-literal规则可补足这些盲区。把规则写进.eslintrc后CI 阶段即可拦截反模式无需依赖人工 review。来自社区与官方文档的依据「我看不出搞很多不同类型有什么价值」就我个人而言我没看到弄很多不同类型的错误对象的价值——JavaScript 作为一种语言似乎不适合基于构造函数的错误捕获。因此区分对象属性似乎比区分构造函数类型容易得多。 —— Ben Nadel 博客Node.js error object 关键词排名第 5「字符串不是错误」传递字符串而不是错误会导致模块间协作性降低。它破坏了与那些可能执行instanceof Error检查、或想了解错误更多信息的 API 之间的约定。错误对象在现代 JavaScript 引擎中拥有非常有趣的属性同时保留传递给构造函数的消息…… —— devthought.com 博客Node.js error object 关键词排名第 6「从 Error 继承不会增加太多价值」我对 Error 类的一个问题是不太容易扩展。当然你可以继承该类并创建自己的错误类如 HttpError、DbError 等。然而这需要时间并且不会增加太多价值除非你是在做一些关于类型的事情。有时你只想添加一条消息并保留内部错误有时你可能希望用参数扩展该错误…… —— machadogj 博客这条观点与仓库立场并不冲突它的本意是反对为每种错误场景各建一个子类而仓库主张的正是只扩展一次Error得到统一AppError其余差异用参数表达。「Node.js 引发的所有 JavaScript 和系统错误都继承自 Error」Node.js 引发的所有 JavaScript 和系统错误都继承自或是 JavaScript 标准 Error 类的实例并保证至少提供该类的可用属性。Error 对象捕获一个stack trace详细说明了错误被实例化时在代码中的位置并可能提供错误的文本描述。由 Node.js 生成的所有错误包括所有系统和 JavaScript 错误都将是 Error 类的实例或继承自 Error 类…… —— Node.js 官方文档这条引用揭示了 Node.js 本身的实践基调整个运行时生态都以Error为统一基类。你的应用层错误模型沿用同一约定才能与系统错误、库错误无缝对接。总结把本实践落到工程上只需记住三条纪律永远throw new Error(...)同步、异步、EventEmitter、Promise 一视同仁绝不抛字符串或裸对象全应用只扩展一次Error得到携带name、httpCode、isOperational等上下文的AppErrorJS 注意原型链修复TS 注意Object.setPrototypeOf用参数而非子类区分错误开启no-throw-literal类 ESLint 规则把规范固化为机器检查。这样做之后你的所有错误都有统一结构、完整堆栈和可判定的操作型属性集中式错误处理2.4、操作型错误判定2.3与优雅退出2.6等后续实践才能真正生效。仓库完整内容可继续阅读 README.md 错误处理章节以及原始文档 useonlythebuiltinerror.md。赞分享文档教程后端【免费下载链接】nodebestpractices✅ The Node.js best practices list (July 2026)项目地址https://gitcode.com/GitHub_Trending/no/nodebestpractices点击查看免费下载相关推荐NW.js Build Flavors 构建变体完全指南SDK 与 Normal 的区别、运行时检测与源码构建NW.js Build Flavors 构建变体完全指南SDK 与 Normal 的区别、运行时检测与源码构建 NW.js 提供多种构建变体Build Fl文档教程后端TypeSpec REST 错误处理实战用 error 错误模型统一 API 异常响应TypeSpec REST 错误处理实战用 error 错误模型统一 API 异常响应 本篇指南聚焦于 TypeSpec 中 REST API 的错误处理编程语言编译器后端Rust 动态错误类型解析用 Box\dyn Error\ 统一处理异构错误comprehensive-rustRust 动态错误类型解析用 Box\dyn Error\ 统一处理异构错误comprehensive rust 导读 Boxdyn Error 是文档教程上一篇5分钟跑通BERTResNet 多模态情感分析实战指南下一篇3步完成视频解密res-downloader加密视频下载与解密完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考