如何处理 express 中第三方中间件抛出的错误?

How do you handle errors thrown from third-party middleware in express?

我们以这段代码为例

const express = require('express')
const bodyParser = require('body-parser')

const app = express()

app.use(bodyParser.urlencoded({ extended: false }))


app.get(...)

# all my routes #

app.use(function (err, req, res, next) {
    console.error(err.stack)
    res.status(500).send('Something broke!')
})

app.listen(9000)
....

如果正文解析器抛出错误?

可能是客户端关闭了连接或者请求负载过大

客户端将从默认的快速错误处理程序收到状态代码为 500 的错误,但这可能是一个应该 return 4xx 响应的错误。

我想在它后面放一个中间件,然后调用 res.send,错误和状态代码为 400。

也许用 try-catch 处理程序包装我所有的第 3 方中间件

或者在我的错误处理程序中间件中添加一个巨大的 switch case 随着时间的推移,添加从中间件第三方中间件抛出的错误并将状态代码更改为 400

所有解决方案都不是真正的螺栓证明,需要随着时间的推移进行维护

我们有什么最佳实践有什么建议吗?

正文解析器模块在遇到错误时应调用 next(err),然后您可以通过提供 Express error handler 来拦截它,例如:

app.use(function(err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Put your content here')
});

当你定义这个特殊的中间件(有四个参数)时,Express 将单独跟踪它作为一个错误处理程序应该被调用 when/if 一些请求处理程序调用 next(err) 或者如果一个同步异常被 Express 捕获。

Express 有一个默认的错误处理程序,如果您不提供您可以阅读有关 here 的信息。但是,如果您提供一个,那么您的将接管并且您可以从错误处理程序中做任何您想做的事情。您甚至可以只记录错误并将用户带到错误页面——如果是网页请求,您甚至不必发送 http 错误状态。如果它是 API,您可能应该使用 http 错误状态。

what is the best practice?

最佳做法是包含您自己的 Express 错误处理程序,您可以在其中拦截发送到 next(err) 的所有错误。

I thought of putting a middleware right after it and calling res.send with the error and status code 400 or maybe wrap all my 3rd party middle ware with try-catch handler

您的第三方中间件需要在 Express 生态系统中正常运行。这意味着它可以同步抛出并且 Express 会自动捕获它并发送给 Express 错误处理程序。代码不应该异步抛出(对于所有类型的代码都是如此),因为没有人可以捕获这些异常(除非它们在 promise 结构的代码中)。您不必自己包装中间件。

内部错误一般不应该是4xx错误,而是5xx错误。您是否将内部错误反馈给最终用户完全取决于上下文。通常,用户会看到某种通用的错误页面。或者,如果它是 API,API 将有一个通信错误的方案,通常 API 将 return 适当映射到问题类型的实际 http 状态代码.

经过进一步调查,这是最适合我的解决方案 在 body parse

之后简单地添加另一个中间件

https://www.npmjs.com/package/express-body-parser-error-handler