入门 Node.js 处理错误
![入门Node.js 处理错误](https://static001.geekbang.org/infoq/7f/7f19a0087eab74667801fb5866afae88.jpeg)
前言
一个健壮性的 Node.js 项目,需要处理好程序错误,本文将带你入门 Node.js 的错误处理。
Error 基础
Node.js 中的错误是 Error 类的任何实例,包括一些内置错误类,还可以扩展基本 Error 类,内置错误类或其他自定义错误来创建用户定义的错误。
JavaScript Error 标准类
message
: 描述错误的信息fileName
: Error 代码所在的文件名lineNumber
: 调用 Error 构造器所在的文件的行号
除通用 Error 外,JavaScript 还有 6 个其他类型的内置错误对象
EvalError
: 表示eval()
有关的错误原因InternalError
: 表示JavaScript
引擎内部异常错误RangeError
: 表示数值变量或参数超出有效范围错误ReferenceError
: 表示引用错误SyntaxError
: 表示语法错误TypeError
: 表示变量或参数类型错误URIError
: 表示给encodeURI()
或decodeURI()
传递的参数无效
这些 Error 对象一旦你抛出它,它就会在堆栈中冒泡,直到在某个地方被捕获到,如果没有捕获到它,它将会变成一个未捕捉到的异常,这可能会导致你的 Node.js 应用程序崩溃。
我们常会遇到的错误类型,往往都是以下的几种情况
JavaScript 标准错误
底层操作系统引发的系统错误
应用程序代码触发的用户指定的错误
assert 断言模块引发的错误
错误处理
同步错误
Node.js 中发生的同步错误,都可以使用 throw 抛出错误,使用 try/catch 捕获错误,如果没有捕获错误,它将向上冒泡,变成 uncaughtException
,从而导致应用程序退出。
异步错误
使用 callback 这种错误优先的回调函数方式,会将错误作为第一参数传递给回调函数。这种错误不能使用
try/catch
捕获
EventEmitter 对象引发的错误,会传递到对象的'error'事件中处理,如果对象没有绑定对应事件,则将错误抛出,错误会冒泡到
process.uncaughtException
捕获。这种错误不能使用try/catch
捕获更现代化的异步 Promise,任何利用错误优先回调进行异步错误的 Node.js API 都可以使用内置的
util.promisify()
方法转为 promise。 Promise 链的错误会在 catch 方法上捕获,如果没有 catch,错误会一直冒泡到顶层,在process.unhandleRejection
上捕获
错误分类
错误分类广泛的区分有 操作错误 和 开发者错误
操作错误
操作错误,是在程序运行时发现的错误。操作错误不是错误,可能会不时发生,主要是由于一种或多种外部因素的组合,例如数据库服务器超时或用户决定通过在输入字段中输入 SQL 查询来尝试进行 SQL 注入这种情况,需要正确处理,避免导致更严重的问题。例如:
网络连接故障
API 请求因某种原因失败
内存溢出
请求超时
无法连接数据库
等等
这种操作错误多数是可预测到的,处理错误
将错误向上报告堆栈,例如 throw 抛出等方式
重试。一些网络请求有时会失败,重试有时会有作用。
有一些崩溃类的错误,会导致程序终止,需要通过日志记录这种错误,便于排查问题并修复它。
开发者错误
这类错误大多情况是开发人员书写的程序逻辑或语法中的错误,这种错误是可以通过源代码更改避免问题的。例如
语法错误
代码逻辑不够严谨
函数参数错误
等等
扩展错误
业务需求开发中,有时你需要扩展错误类,方便业务记录错误日志消息等。需要基于 Error 做一些封装。例如:
ApplicationError
这是所有其他错误类的基类,即所有其他错误类都继承自它DatabaseError
与数据库操作相关的任何错误都将从此类继承。
例如:
这种方法使我们能够区分应用程序抛出的错误。所以现在如果我们要处理错误的请求错误(无效的用户输入)或未找到的错误(未找到资源),我们可以从 UserFacingError
基类继承(如下面的代码所示)
错误日志
所有的生产项目,应该都需要有对应的持久化错误日志,记录信息便于追踪、排查错误原因。
常用库有 log4js
、winston
,下面以log4js
作为使用例子
![](https://static001.geekbang.org/infoq/69/69f25723ab948360d7e08f2fe4ca1ead.png)
上面只是在控制台打印了日志,生产项目需要保存日志到本地,详细可以查看 log4js
文档。
总结
本文主要是简单介绍了 Node.js 开发中对于错误的处理。对于业务层的错误抽象还可以更复杂些,避免在业务代码重复写 try/catch 等错误处理逻辑。
行文仓促,如果文中有表述不准确的地方,欢迎指正。
我是废材壶,前端开发者,欢迎微信搜一搜「 CodeLife 集」阅读不迷路
参考
版权声明: 本文为 InfoQ 作者【废材壶】的原创文章。
原文链接:【http://xie.infoq.cn/article/a51ca02e0689e58c1007ac355】。文章转载请联系作者。
评论