快速处理异常 [英] Handling exceptions in express

查看:111
本文介绍了快速处理异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解如何处理快递似乎很基本的方面时遇到了麻烦。如果我有一些代码在异步回调中引发异常,则无法捕获该异常,因为在回调运行时try / catch块不再在作用域内。在这些情况下,浏览器将挂起,直到最终放弃声明服务器没有响应。这是非常糟糕的用户体验。我更希望能够立即将500错误返回给客户端。默认的express错误处理程序显然不能处理这种情况。下面是一些示例代码:

I'm having trouble understanding how to handle something that it seems like would be a pretty basic aspect of express. If I have some code that throws an exception in an async callback, there is no way I can catch that exception because the try/catch block is no longer in scope by the time the callback is running. In these scenarios the browser will hang until it eventually give up stating that the server is unresponsive. This is a very bad user experience. I would much rather be able to immediately return a 500 error to the client. The default express error handler apparently does not handle this situation. Here is some sample code:

var express = require("express");

var app = express();
app.use(app.router);
//express error handler (never called)
app.use(function(err, req, res, next) {
    console.log(err);
    res.send(500);
});

app.get("/test", function(req, res, next) {
    require("fs").readFile("/some/file", function(err, data) {
        a.b(); //blow up
    });
});

app.listen(8888);

在上面的代码中,行ab()抛出 ReferenceError:a not defined异常。永远不会调用已定义的错误处理程序。请注意,在这种情况下,由于已正确读取文件,因此fs.readFile()返回的err对象为null。该错误是异步处理程序中的代码。

In the above code, the line a.b() throws a "ReferenceError: a is not defined" exception. The defined error handler is never called. Notice that the err object returned by fs.readFile() is null in this case because the file was correctly read. The bug is the code inside the async handler.

我已阅读这篇文章关于甚至使用节点的uncaughtExpception,但文档说不使用该方法。即使我确实使用过它,又如何将500响应发送回用户?快速响应对象不再可供我使用。

I have read this post about using node's uncaughtExpception even, but the documentation says not use that method. Even if I did use it, how would I then send the 500 response back to the user? The express response object is no longer around for me to use.

那么您如何处理这种情况?

So how do you handle this scenario?

推荐答案

好的,我要发布一个完全不同的答案,因为我的第一个答案具有一些有价值的信息,但事后看来却不在主题之列。

OK, I'm just going to post an entirely different answer since my first answer has some valuable information but is off topic in hindsight.

简短的答案:正确的事情已经发生了:您的程序应打印堆栈跟踪并退出并出现错误。

The short answer: the correct thing to do is what already happens: your program should print a stack trace and exit with an error.

基本思想

因此,我认为您需要考虑不同类别的错误。我的第一个答案涉及编写得当的程序可以并且应该干净地处理与数据相关的错误。您所描述的是一次CRASH。如果您阅读链接到的node.js文档,那是正确的。此时程序唯一可以做的有用的事情就是退出堆栈跟踪,并允许流程管理器重新启动它并获得可理解的状态。一旦程序崩溃,由于错误的范围很广,因此基本上无法恢复,这可能是导致异常到达堆栈顶部的根本原因。在您的特定示例中,此错误将每次都继续发生,直到修复了源代码错误并重新部署了应用程序为止。如果您担心未经测试且错误的代码会进入您的应用程序,那么添加更多未经测试且错误的错误处理代码并不能真正解决正确的问题。

So I think you need to think about errors in different categories. My first answer deals with data-related errors that a well-written program can and should handle cleanly. What you are describing is a CRASH. If you read the node.js documentation you linked to, it is correct. The only useful thing your program can do at this point is exit with a stack trace and allow a process supervisor to restart it and attain an understood state. Once your program has crashed, it is essentially unrecoverable due to the extremely wide range of errors that could be the root cause of an exception getting to the top of the stack. In your specific example, this error is just going to continue happening every time until the source code bug is fixed and the application is redeployed. If you are worried that untested and buggy code is going to get into your application, adding more untested and buggy error handling code isn't really addressing the right problem.

简而言之,没有,没有办法获取导致此异常的HTTP请求对象的引用,因此AFAIK除了在中间反向代理层进行处理外,您无法更改最终用户在浏览器中的感知方式您可以配置粗略的超时并发送更友好的错误页面(对于非完整HTML文档的请求,这当然毫无用处)。

But in short, no, there's no way to get a reference to the HTTP request object that caused this exception so AFAIK you cannot change the way this is perceived by the end user in the browser, outside of handling this at an intermediate reverse proxy layer where you could configure a crude timeout and send a more friendly error page (which of course would be useless for any request that isn't for a full HTML document).

节点中错误处理的圣经

中的错误处理是有关该主题的权威著作。它是全面,广泛和彻底的。我建议定期阅读和重新阅读。

Error Handling in Node.js by Dave Pacheco is the definitive work on this topic in my opinion. It is comprehensive, extensive, and thorough. I recommend reading and re-reading periodically.

如果未处理的异常很容易重现或发生,请解决@asparagino的评论。高频率,这不是一个极端的情况,这是一个错误。正确的做法是改进您的代码,以面对这种情况不会生成未捕获的异常。实际上处理了这种情况,从而将程序员错误转化为操作错误,并且您的程序可以继续运行而无需重新启动并且没有未捕获的异常。

To address @asparagino's comments, if an unhandled exception is easily reproducible or happening with high frequency, it's not an edge case, it's a bug. The correct thing to do is improve your code to not generate uncaught exceptions in face of this situation. Actually handle the condition, thus converting a programmer error into an operational error, and your program can continue without a restart and without an uncaught exception.

这篇关于快速处理异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆