首页 > 解决方案 > 如何从 Node.Js 应用程序中处理 Express 4 中的错误?

问题描述

我升级到 Express 4 并在错误处理方面遇到以下问题。

在我使用代码之前app.js- 在我拥有所有可能的路线之后

var routes = require('./routes')
app.use(routes.notfound)
app.use(routes.error)
app.use(routes.badrequest)

然后在里面/routes/index.js我有:

exports.notfound = function(req, res) {
    res.status(404).format({
        html: function() {
            res.render('404')
        },
        json: function() {
            res.send({
                message: 'We did not find what you were looking for :(',
            })
        },
        xml: function() {
            res.write('<error>\n')
            res.write(
                ' <message>We did not find what you were looking for :(</message>\n'
            )
            res.end('</error>\n')
        },
        text: function() {
            res.send('We did not find what you were looking for :(\n')
        },
    })
}

现在,当我在应用程序的其他地方(不是在app.js)中调用 404 时,res.send(404)我得到了正确的 404 代码响应,但我没有到达它选择是否显示 html 或 json 或文本的部分。

我怎么做?

标签: node.jsexpressexpress-4

解决方案


您需要以不同的方式处理错误捕获,这是一种方法:

在所有路由之后创建一个中间件,该中间件将捕获您传递给它的错误,回调将接受一个包含有关错误详细信息的额外参数:

app.use((err, req, res, next) => {
  // Handle the error here
});

每当你想呈现错误时,你可以next在你的路由中使用它来将它传递给这个中间件,并传递你可以用来决定如何处理错误的额外信息。有一个名为http-errors的模块可以为您创建类似的对象。这是一个示例路线:

const createError = require('http-errors');

app.get('/posts', (req, res, next) => {
  // Logic...
  if(/* some condition */) {
    next(createError(404));
  }
});

这会将创建的错误对象传递给您的错误处理中间件,然后您可以从那里选择如何处理它。

为了扩展这一点,并使其更好地与异步代码一起工作,您可以使用一个函数包装路由器的回调,该函数将确保将抛出的异常传递给错误处理中间件,这在使用asyncand时会派上用场await

// Wrapper function to forward errors from async scopes
const wrap = fn => (...args) => fn(...args).catch(args[2]);

app.get('/posts', wrap(async (req, res) => {
  // Logic...
  await controller.get('posts'); // Promise rejections will get forwarded to middleware
}));

这也允许您只throw使用错误对象而不是调用next.


推荐阅读