YSS

Write Less & Do More

Node.js中的错误及对应的处理

前言

Node.js是前端人员步入后台开发的通道。学会了js就基本前后端通吃。但事实真的是这样子的么?

目前虽然说有很多公司在使用Node.js,但是真实应用在生产环境中的项目还是很少。不过已经逐步看到越来越多的传统公司在开始使用Node.js做后台应用了。

错误

错误分两种,一种是操作错误,一种是程序错误。

操作错误

操作错误主要是运行时错误,并不是真正的bug。比如:

  1. 外部服务无法连接
  2. 网络不可用
  3. 请求超时
  4. 内存溢出

程序错误

就是我们通常意思上说的bug,也就是可以在程序上进行避免的错误。比如:

  1. 操作一个不存在的对象属性
  2. 解析一个非法字符串
  3. 错误的运算

错误处理

由于JavaScrip的弱语言特性,导致JavaScript异常的灵活,有很多的不可控因数在里面。

另外,由于Node.js的异步特性,导致监听也是个问题。

而且最最关键的点,一个地方的错误,会导致整个程序的crash。

所以,在写Node.js程序时,更需要一个可靠,完善的错误处理机制。

这里依旧分别阐述两种不同的错误处理方式。

操作错误处理

操作错误是不可预期的错误,也是无法完全避免的错误。所有我们能做的就是:

  1. 直接处理这个错误,当然你也可以是忽略,然后继续下一步处理
  2. 直接把错误打到你的客户端中。
  3. 重试当前的操作。
  4. 直接crash掉程序,比如内存溢出就是JavaScript处理不了的。
  5. 仅仅打印当前的错误日志。

程序错误处理

说到程序错误,那就肯定是我们开发人员的锅了。

本质就是程序写得不健壮。

一般来说,针对程序错误,我们需要额外小心,因为它很可能会导致内存泄露。

如果是没有捕获到的错误,则必须重启应用。

正确的分发错误

写一个程序,特别是一个组件或功能,很多时候你是不知道外部环境的。

当遇到错误时,你所能做到的就是把这个错误分发出去。

那么分发分哪几种呢?

  1. throw 顾名思义就是直接抛出异常,外层通过try,catch来捕获异常。
  2. Callbacks 也就是回调函数callback(er, result)
  3. EventEmitter 事件模型。

需要注意的是

  1. 如果使用throw则一定不能同时使用下面两个分发方式。
  2. CallbacksEventEmitter可以同时存在。
  3. EventEmitter则必须是使用’error’事件发出,且此时监听的事件中必须包含error的事件处理。

那最后一条为什么一定要用error这个名字的事件呢?原因就是,如果异常不被及时处理很容易导致内存泄露,如果事件名变成error后,它可以帮你自动抛到最外层的处理函数。这个时候一个uncaught的进程错误事件就抛出了。具体可以说明可以参考:https://nodejs.org/dist/latest-v4.x/docs/api/events.html#events_error_events

所以,归纳起来,正常的处理应该是这样。

  1. 首先看有没有错误事件监听,有的话,调用错误事件监听。
  2. 再则看有没有回调函数,有回调函数则直接转到回调函数。
  3. 如果以上都没有的话,则直接通过throw抛出异常。

最后

很多前端人员,包括我自己,最开始在开发Node.js的程序时,都没有一个严谨的思想,这导致程序写得一点都不健壮,动不动就可能会挂。

我想都是被浏览器给惯坏了,很少会去注意检查变量,检查值是否存在,检测对象是否可用。

所以,在我看来,在开发Node.js的应用过程中,首页需要做的就是确定一个严谨的后台开发理念。然后才是正式的开发。

最后就是,一定要加上日志和各种各样的异常处理。