Express框架进阶3---错误处理

Error Handling(https://www.expressjs.com.cn/guide/error-handling.html)

本文的【错误处理】指Express如何捕获和处理(同步和异步的)错误。Express有一个默认的错误处理handler,所以一开始不是必须写自己的错误处理handler。

捕获错误
Catching Errors

保证Express会捕获运行路由handlers和中间件时发生的所有错误非常重要。
在路由handlers和中间件的同步代码中发生的错误不需要做额外的工作(Errors that occur in synchronous code inside route handlers and middleware require no extra work),Express会捕获和处理。
但路由handlers和中间件中调用的异步函数抛出的错误,我们就需要将异常捕获,使用next()函数 将错误传入(next(error)), 使Express能够捕获和处理这个错误。
tips:next函数除了传入字符串'route',其他参数都会被认为是错误,会跳过余下所有非错误处理的路由和中间件函数

// 
app.get('/', [
  function(req, res, next) {
    fs.writeFile('/file-does-not-exit', data, function(err, data){
      if(err) {
        next(err);
      } else {
        res.send(data);
      }
    });
  }
])
// 直接将next作为callback函数,
//有错误时next有参数 携带错误参数被Express error handler捕获并处理,
// 无错误时 next无参数 , 执行下一个handler
app.get('/', [
  function(req, res, next) {
    fs.writeFile('/file-does-not-exit', data, function(err, data){
      if(err) {
        next(err);
      } else {
        res.send(data);
      }
    });
  }
])
// 需捕获异常
app.get('/', function (req, res, next) {
  setTimeout(function () {
    try {
      throw new Error('BROKEN')
    } catch (err) {
      next(err)
    }
  }, 100)
})
// 使用promise 代替 try catch
app.get('/', function (req, res, next) {
  Promise.resolve().then(function(){
    throw new Error('BROKEN')
  }).catch(next)
})

默认的错误处理函数
The default error handler

没有自定义错误处理函数,用next(error)传入错误的时候,express默认的错误处理函数进行处理,会同时输出调用栈信息(NODE_ENV的值为production时不会打印调用栈信息)
需要注意的一点是,如果已经开始写response,调用了next(error), Express的默认错误处理函数会关闭连接,此次请求会失败。
所以在自定义的error handler中,当header已经被发送给client端,发生错误的话需要将错误传给默认的错误处理函数(???)

如果你在你的代码调用next()出现错误多次,则会触发默认错误处理程序,即使自定义错误处理中间件已就绪也是如此(???)

function errorHandler (err, req, res, next) {
  if (res.headersSent) {
    return next(err)
  }
  res.status(500)
  res.render('error', { error: err })
}

如何实现错误处理函数
Writing error handlers

定义错误处理中间件函数的方式与定义其他中间件函数一样,只是错误处理中间件的参数是4个 err, req,res ,next

我们需要在最后定义错误处理中间件函数,在其他的app.use 和路由调用之后。

中间件函数的返回值可以是任意格式,如html错误页面,简单的字符串信息 或json字符串
如果在error handler中没有调用next函数,则需要负责返回响应,否则请求会被挂起,并且不会被垃圾回收机制回收

你可能感兴趣的:(Express框架进阶3---错误处理)