我正在尝试理解express中的错误处理。TrustIP函数是一个中间件,它通过调用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)
}
3条答案
按热度按时间yizd12fk1#
对于the docs,它们基本上做同样的事情。但是,在异步(在处理程序中调用的函数在此上下文中具有回调)函数(例如
fs.readFile
)中,您将需要使用回调并在内部传递错误。我自己还没有测试过,但我很确定这是因为如果实际上没有错误,并且错误只能通过回调的参数(比如
fs.readFile
)看到,那么就不会向客户端发送任何响应,客户端将永远等待响应。bybem2ql2#
在
trustIp
函数中,next(new Error('err'))
和throw new Error('err')
将执行完全相同的操作。你可以通过在
trustIp
函数中放置一个断点并检查express中调用它的代码来证明这一点。如果您的函数抛出错误,express只会捕获它并调用
next
函数。但是有一点很重要,如果你把
trustIp
变成一个异步函数,情况就不同了,在这种情况下,它不再是一个抛出错误的函数,而是一个返回拒绝承诺的函数,这是不同的事情,而express(版本4)不知道如何处理它,这就是为什么在代码中调用next(err)
通常是使用express时养成的一个好习惯。lb3vh1jj3#
因此,一般来说,处理错误和重新抛出错误之间的区别在于谁负责处理错误的问题。
案例1)假设您创建了一个API,在其中您将电话号码输入到输入字段中。该方法不接受字母。它只接受数字。此时,您将假设使用您的代码的程序员需要将错误传递回用户,并告诉他们只能输入数字。用户虽然输入了字母。此时,您可以将错误返回给调用它的人,这样他们就可以告诉用户更正它。
情况2)当由于调用者无法控制的原因而发生错误时,代码会处理该错误,然后记录该错误并可能打开一个页面。如果服务器关闭,则可能发生这种情况,而您的调用取决于服务器是否启动。此时,你用一个有意义的错误代码来处理这个错误,告诉用户大概发生了什么。2你的方法的调用者不能做任何事情来解决它。3当你处理一个错误时,在日志中为调试人员提供尽可能多的信息,以便他们能够找出问题发生的原因。