4

我的domain模块有问题。目前,我正在尝试捕获请求中抛出的任何未捕获的错误。使用express中间件和域。所有请求都通过此函数进行路由,然后再调用next并转到正确的路由。

app.use (req, res, next) ->
    domain = createDomain()
    domain.on "error", (err) ->
        res.send(500)
        domain.dispose()

    domain.enter()
    next()

问题是,如果从未抛出错误,我该如何处理域?

我可以在中间件之外提升域和事件,所以我不必处理,但是我将无法访问我需要发送 500 的中间件参数。

有没有人对我如何处理这个问题有更好的解决方案?我花了太多时间试图找出一种方法(以及许多 hacky 方法)来处理这个问题。谢谢。

4

1 回答 1

5

domain.dispose()如果没有发生错误,您不需要调用。的目的domain.dispose()是清理任何在跳出堆栈中间后处于不确定状态的资源,并抑制由于状态不佳而可能发生的后续错误。的反向调用domain.enter()很简单domain.exit()

也就是说,浏览域的代码,看起来您不想以这种方式使用domain.enter/ 。exit每个 domain.enter/exit 对应于 domain 模块代码中一个共享数组的栈 push/pop。因此,例如,如果第二个请求在第一个请求完成之前进入,然后第一个请求在第二个完成之前退出,则在第一个域处理程序中调用 exit 将弹出第二个请求的域。似乎很有可能进入和退出不应该在异步事物中分开。

您是否尝试过简单地使用domain.run(next)?这似乎对我有用。它基本上是为你进入域,然后调用你给它的回调,然后在回调返回后立即退出域。在域中创建的任何计时器或事件发射器也将与该域相关联。事件发射器在调用事件处理程序时也使用类似的进入-调用-退出模式。从代码中可以看出,跟踪事件处理程序的不是域,而是跟踪域的事件处理程序。

简而言之,不要尝试将 enter 与 dispose 配对,也不要尝试跨异步边界使用 enter/exit。使用运行/绑定/添加/删除。

于 2013-03-06T10:14:11.673 回答