Javascript 如何正确处理 Express 中的错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7716691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:18:36  来源:igfitidea点击:

How to properly handle errors in Express?

javascriptnode.jsmiddlewareexpress

提问by YWCA Hello

I am beginning to work with Express JS and have run into an issue. I can't seem to figure out the proper way to handle errors.

我开始使用 Express JS 并遇到了一个问题。我似乎无法找出处理错误的正确方法。

For example, I have a web services API that serves an object called "event". I'd like to return a simple string of "cannot find event" when a user submits an event id that isn't found. Here is how I'm currently structuring my code:

例如,我有一个 Web 服务 API,它为一个名为“事件”的对象提供服务。当用户提交未找到的事件 ID 时,我想返回一个简单的“找不到事件”字符串。这是我目前构建代码的方式:

app.get('/event/:id', function(req, res, next) {
    if (req.params.id != 1) {
        next(new Error('cannot find event ' + req.params.id));
    }

    req.send('event found!');
});

When I submit an idother than 1, Node crashes with the following output:

当我提交1 以外的id 时,Node 崩溃并显示以下输出:

http.js:527
   throw new Error("Can't set headers after they are sent.");
         ^
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/usr/local/kayak/node_modules/express/node_modules/connect/lib/patch.js:62:20)
    at /usr/local/kayak/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js:72:19
    at [object Object].<anonymous> (fs.js:107:5)
    at [object Object].emit (events.js:61:17)
    at afterRead (fs.js:878:12)
    at wrapper (fs.js:245:17)

From what I can tell by using the node.js debugger, execution of the block of code continues after next()is called, meaning that req.send('event found!')tries to run. I don't want this to happen.

从我使用 node.js调试器可以看出,代码块的执行在next()被调用后继续执行,这意味着它会req.send('event found!')尝试运行。我不希望这种情况发生。

The only workaround that I've found is to simply throw a new Error()instead of "next-ing" it, but this results in a default Express HTML error page being generated. I'd like a little more control than that.

我发现的唯一解决方法是简单地抛出一个new Error()而不是“next-ing”它,但这会导致生成默认的 Express HTML 错误页面。我想要更多的控制权。

I have taken the time to read over the error handling sectionof the Express documentation, but I couldn't make sense of it.

我花时间阅读了Express 文档的错误处理部分,但我无法理解。

回答by Chance

You'll want to check out Express Error Handling. From there:

您需要查看Express Error Handling。从那里:

app.param('userId', function(req, res, next, id) {
    User.get(id, function(err, user) {
        if (err) return next(err);
        if (!user) return next(new Error('failed to find user'));
        req.user = user;
        next();
    });
});

The sweetspot that you are missing is the returnnext(...)

你缺少的甜蜜点是 returnnext(...)

回答by alessioalex

That's because you're doing it wrong: you already threw an Error (which will be processed by Express and return a 500 - Error page for the user or something like that) but you are also trying to send your own response to the client: res.send('event found!');

那是因为你做错了:你已经抛出了一个错误(它将被 Express 处理并为用户返回一个 500 - 错误页面或类似的页面)但你也试图将自己的响应发送给客户端: res.send('找到事件!');

You should really check out the Express guide about Error Handling here: http://expressjs.com/guide/error-handling.html

你真的应该在这里查看关于错误处理的 Express 指南:http: //expressjs.com/guide/error-handling.html

What I would do in your example is:

我在你的例子中会做的是:

function NotFound(msg){
  this.name = 'NotFound';
  Error.call(this, msg);
  Error.captureStackTrace(this, arguments.callee);
} 

app.get('/event/:id', function(req, res, next){
  if (req.params.id != 1) {
    throw new NotFound('Cannot find event ' + req.params.id);
  } else {
    res.send('event found!');
  }
});

app.error(function(err, req, res, next){
    if (err instanceof NotFound) {
        res.render('404.ejs');
    } else {
        next(err);
    }
});

回答by evilcelery

You have a couple of problems in your code:

您的代码中有几个问题:

  • When responding to the client, you need to use the responseobject(resrather than req).

  • When sending an error to next, you should return, so the rest of the function doesn't run.

  • 响应客户端时,需要使用响应对象res而不是req)。

  • 向 发送错误时next,您应该返回,因此函数的其余部分不会运行。

Here's your code after fixing those errors:

这是修复这些错误后的代码:

app.get('/event/:id', function(req, res, next) {
    if (req.params.id != 1) {
        return next(new Error('cannot find event ' + req.params.id));
    }

    res.send('event found!'); // use res.send (NOT req.send)
});