【问题标题】:Do exceptions get caught in lambdas in javascript / node.js?javascript / node.js 中的 lambdas 是否会捕获异常?
【发布时间】:2011-02-22 21:47:55
【问题描述】:

我有一个 node.js 服务器,我希望能够在不崩溃的情况下处理异常,并且我的代码有点像下面。我想知道的是,有了所有事件驱动的出色功能、回调和 lambda 以及所有这些,我的异常是否仍会被我的主要入口点捕获?

try {

  http.get(..., function(results) {
    // Might get an exception here
    results.on('data', function () {
      // Might also get an exception here
    });
    results.on('end', function () {
      // Might also get an exception here
    });
  });

} catch(e) {
  // Will the exceptions from the lambdas be caught here?
  console.log('Nicely caught error: (' + e.name + '): ' + e.message);
}

谢谢

【问题讨论】:

标签: javascript exception node.js


【解决方案1】:

这取决于控制流。 Node.js 强调异步性,而异步性的主要缺点之一是代码不会以您可能习惯于使用同步语言的方式流动。

在同步语言中,调用者在函数等待某些数据时被阻塞。这让程序员的工作变得相当简单,因为他们可以保证当等待数据的函数返回时,会有数据供调用者使用。

这与异步语言或非阻塞 I/O 完全相反。在这种情况下,调用者在函数调用期间被阻塞,但是函数在返回之前不必等待数据或 I/O 完成。这使程序员的工作变得更加困难,因为当函数调用返回时,无法保证是否有可用的数据。因此,非阻塞 I/O 通常意味着当数据可用于操作时调用的回调函数。

try/catch 块与调用堆栈一起工作。也就是说,当抛出异常时,运行时将展开调用堆栈,直到找到一个围绕抛出异常的调用的catch 块。但是,由于http.get 是一个非阻塞调用,它在注册一些回调并继续处理后立即退出。回调在单独的“线程”中调用,因此这些调用不会嵌套在原始 try/catch 块中。

图表确实可以帮助解释这里的事情,但不幸的是我没有可用的图表。

【讨论】:

  • 听起来如我所料。那么如何编写一个能够在偶尔出现的异常中幸存下来的 node.js 服务器呢?您是否只是编写一个监视进程,在它死后重新启动它?对我来说听起来有点不幸。
  • 您会遇到什么样的异常?理想情况下,node.js 会有一个错误回调,允许您执行任何需要的清理。
  • 现实情况是回调非常糟糕,这也是原因之一。查看reactive programming 以获得更可口的风格。
  • 我同意,node.js 是新的热点,但我不完全确定为什么会这样。肯定有更美味、更容易推理的东西。
【解决方案2】:

node.js 标准库的错误处理方式是调用相同的回调,但传递一个非空的第一个参数来表示错误。如果您的异步代码中有异常情况,请保持该格式。

一个 throw 会爬上调用链,它通常不知道回调在做什么(例如,tcp 层不关心它的数据是否被解析为 http)。可抛出的异常不适合异步编程。

【讨论】:

    【解决方案3】:

    在您的示例代码中,从 http.get 回调中抛出的任何潜在异常都不会出现在您的 catch 块中。当数据可供读取时,回调的堆栈是从节点的事件循环中构建的。

    有一种方法可以在节点中捕获未捕获的异常:

    process.on("uncaughtException", function (err) {
        console.log("uncaught exception: " + err);
    });
    

    这对您的示例有点作用,具体取决于异常的位置。

    问题是,未捕获的异常会以令人惊讶的方式解开节点的内部运作,所以你真的不想依赖这个。以您可以处理的方式捕获所有可能的异常的唯一可靠方法是在事件循环的每个入口点周围放置一个 try/catch。

    这听起来很乏味,但通常并没有那么糟糕。在您的示例程序中,您将节点的 API 用于 HTTP 请求,这仍然是一个非常低级的接口。在大多数情况下,您希望将这个异常捕获功能封装一次并将其用作库。

    【讨论】:

      猜你喜欢
      • 2018-01-29
      • 2015-02-06
      • 1970-01-01
      • 1970-01-01
      • 2018-09-06
      • 2015-11-14
      • 2011-04-10
      • 1970-01-01
      • 2010-09-25
      相关资源
      最近更新 更多