[英]Error handling in ExpressJS middlewares, next() vs throw
我试图了解快递中的处理错误。 TrustIP function 是一个中间件,它通过调用next(new Error('err'))
传递错误,但也可以通过throw new Error
来传递错误。 两者似乎都有效,正确的方法是什么,为什么? 我还在学习。 谢谢你的时间。
function trustIP(req, res, next) {
const trustedIPs = ['**.**.**.**']
let requestIP = req.headers['x-forwarded-for'] || req.socket.remoteAddress
if (requestIP.substr(0, 7) === '::ffff:') {
requestIP = requestIP.substr(7)
}
if (trustedIPs.indexOf(requestIP) >= 0) {
next()
} else {
next(new Error(`Not trusted IP: ${requestIP} tryed to connect`))
// throw new Error ???
}
}
app.use('/', trustIP, navRoutes)
app.use(errorHandler)
app.listen(process.env.PORT, () => console.log(`Server on port: ${process.env.PORT}`))
const errorHandler = (err, req, res, next) => {
console.error('error handler:', err.stack)
res.status(500).send(err.message)
}
根据文档,他们基本上做同样的事情。 但是,在异步(在此上下文中使用回调在处理程序中调用的函数)function(例如fs.readFile
)中,您将需要使用回调并将错误传递给内部。
// synchronous, just throw
app.get('/', (req, res) => {
throw new Error('BROKEN') // Express will catch this on its own.
})
// asynchronous, pass to callback
app.get('/', (req, res, next) => {
fs.readFile('/file-does-not-exist', (err, data) => {
if (err) {
next(err) // Pass errors to Express.
} else {
res.send(data)
}
})
})
我自己还没有测试过,但我很确定这是因为如果没有实际抛出错误并且错误仅通过回调参数(比如fs.readFile
)可见,则永远不会发送任何响应客户和他们将永远等待响应。
在你的trustIp
function 中, next(new Error('err'))
和throw new Error('err')
会做同样的事情。
您可以通过在trustIp
function 中放置一个断点并检查调用它的 express 中的代码来证明这一点。 这是你会在那里找到的:
try {
fn(req, res, next);
} catch (err) {
next(err);
}
如果您的 function 抛出错误,express 会简单地捕获它并调用next
function。
但重要的是要了解,如果将trustIp
为异步 function,情况就会有所不同。在这种情况下,抛出错误的不再是 function,而是返回将拒绝的 promise 的 function。 那是另一回事,express(版本 4)不知道如何处理它。 这就是为什么在代码中调用next(err)
通常是使用 express 时养成的好习惯。
因此,一般来说,处理错误和重新抛出错误之间的区别在于由谁负责处理错误的问题。
案例 1) 假设您创建了一个 API,您在其中将电话号码输入到输入字段中。 该方法不接受字母。 它只需要数字。 这时,你会假设正在使用你的代码的程序员需要将错误返回给用户并告诉他们只能输入数字。 用户虽然输入了字母。 此时,您会将错误返回给调用它的人,以便他们可以告诉用户更正它。
情况 2) 当某些事情由于调用者无法控制的事情而发生时,错误被处理,然后代码通过记录它并可能调出一个页面来处理错误。 如果服务器关闭,则可能会发生这种情况,而您的调用取决于服务器是否启动。 那时,您使用有意义的错误代码来处理错误,告诉用户大致发生了什么。 您的方法的调用者无法解决它。 当您处理错误时,请在日志中尽可能多地为调试人员提供更多信息,以便他们找出问题发生的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.