异常位置的Node.JS异步错误的合理处理方案

时间:2013-12-07 00:39:09

标签: node.js error-handling

在Java中,我习惯尝试.catch,最后清理未使用的资源。

在Node.JS中,我没有这种能力。

可能会出现奇数错误,例如数据库可能随时关闭,任何单个表或文件都可能丢失等等。

db.query(..., function(err, results){...进行嵌套调用,每次调用if(err) {send500(res); return}变得非常繁琐,尤其是,如果我必须清理资源,例如db.end()肯定会适当的。

如何编写使异步捕获并最终阻止两者的代码?

我已经知道重启过程的能力,但我想将其作为最后的手段使用。

1 个答案:

答案 0 :(得分:1)

对此的完整答案非常深入,但它是以下的组合:

  • 始终如一地处理回调函数中的error位置参数。在这里加倍应该是你的第一步。
    • 你会看到@izs将其称为“样板”,因为无论你是在做回调还是承诺还是流程控制库,你都需要很多。由于异步性质,没有很好的方法可以在节点中完全避免这种情况。但是,您可以通过使用辅助函数,连接中间件等来最小化它。例如,我有一个帮助器回调函数,每当我进行数据库查询时我都会使用它,并打算将结果作为JSON发送回API响应。该函数知道如何处理错误,找不到错误,以及如何发送响应,这样可以大大减少我的样板。
  • 根据@izs's blog post
  • 使用process.on('uncaughtExcepton')
  • try/catch用于偶尔引发异常的同步API。很少见,但有些图书馆会这样做。
  • 考虑使用domains。域名会让你更接近java范例,但到目前为止,我没有看到太多关于它们的讨论,这使我预计它们在节点社区中尚未被广泛采用。
  • 考虑使用cluster。虽然没有直接关系,但它通常与这种类型的生产稳健性密切相关。
  • 某些库有顶级错误事件。例如,如果您使用mongoose与mongodb通信并且连接突然终止,则连接对象将发出错误事件

这是一个例子。用例是由数据库支持的REST / JSON API。

//shared error handling for all your REST GET requests
function normalREST(res, error, result) {
  if (error) {
    log.error("DB query failed", error);
    res.status(500).send(error);
    return;
  }
  if (!result) {
    res.status(404).send();
    return;
  }
  res.send(result); //handles arrays or objects OK
}


//Here's a route handler for /users/:id
function getUser(req, res) {
  db.User.findById(req.params.id, normalREST.bind(null, res));
}

我认为我的内容是整体上在JavaScript本身,错误处理基本上是不充分的。在浏览器中,您刷新页面并继续您的生活。在节点中,它更糟糕,因为您正在尝试编写一个健壮且长期存在的服务器进程。有一个completely epic issue comment on github详细说明了事情是如何从根本上被打破的。我不希望你拥有可以指出的JavaScript代码并说“Look,Ma,最先进的错误处理”。也就是说,在实践中,如果你遵循我上面列出的观点,根据经验,你可以编写足够强大的程序来制作。

另见The 4 Keys to 100% Uptime with node.js