如何处理 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
我们以这段代码为例
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