javascript ExpressJS中间件中的错误处理,next()与throw

5ssjco0h  于 2022-12-28  发布在  Java
关注(0)|答案(3)|浏览(170)

我正在尝试理解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)
}
yizd12fk

yizd12fk1#

对于the docs,它们基本上做同样的事情。但是,在异步(在处理程序中调用的函数在此上下文中具有回调)函数(例如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)看到,那么就不会向客户端发送任何响应,客户端将永远等待响应。

bybem2ql

bybem2ql2#

trustIp函数中,next(new Error('err'))throw new Error('err')将执行完全相同的操作。
你可以通过在trustIp函数中放置一个断点并检查express中调用它的代码来证明这一点。

try {
  fn(req, res, next);
} catch (err) {
  next(err);
}

如果您的函数抛出错误,express只会捕获它并调用next函数。
但是有一点很重要,如果你把trustIp变成一个异步函数,情况就不同了,在这种情况下,它不再是一个抛出错误的函数,而是一个返回拒绝承诺的函数,这是不同的事情,而express(版本4)不知道如何处理它,这就是为什么在代码中调用next(err)通常是使用express时养成的一个好习惯。

lb3vh1jj

lb3vh1jj3#

因此,一般来说,处理错误和重新抛出错误之间的区别在于谁负责处理错误的问题。
案例1)假设您创建了一个API,在其中您将电话号码输入到输入字段中。该方法不接受字母。它只接受数字。此时,您将假设使用您的代码的程序员需要将错误传递回用户,并告诉他们只能输入数字。用户虽然输入了字母。此时,您可以将错误返回给调用它的人,这样他们就可以告诉用户更正它。
情况2)当由于调用者无法控制的原因而发生错误时,代码会处理该错误,然后记录该错误并可能打开一个页面。如果服务器关闭,则可能发生这种情况,而您的调用取决于服务器是否启动。此时,你用一个有意义的错误代码来处理这个错误,告诉用户大概发生了什么。2你的方法的调用者不能做任何事情来解决它。3当你处理一个错误时,在日志中为调试人员提供尽可能多的信息,以便他们能够找出问题发生的原因。

相关问题