资讯专栏INFORMATION COLUMN

如何处理Express异常?

justjavac / 1928人阅读

摘要:处理异常是编程非常重要的一点。我们的程序依赖于第三方服务数据库以及我们的用户,一切都不可预料。为了处理这些错误,需要添加一个中间件,它有个参数这样,我们就可以使用中间件统一处理错误了。

译者按:根据墨菲定律:“有可能出错的事情,就会出错”。那么,既然代码必然会出错,我们就应该处理好异常。

原文: How to handle errors in Express

译者:Fundebug

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

处理异常是编程非常重要的一点。我们的程序依赖于第三方服务、数据库以及我们的用户,一切都不可预料。数据库可能会宕机,第三方服务可能会崩溃,用户可能会使用错误的参数调用我们的接口。

为了处理各种复杂的情况,我们必须处理好代码异常,下面是代码示例:

app.get("/users/:id", (req, res) => {
  const userId = req.params.id
  if (!userId) {
    return res.sendStatus(400).json({
      error: "Missing id"
    })
  }

  Users.get(userId, (err, user) => {
    if (err) {
      return res.sendStatus(500).json(err)
    }

    res.send(users)
  })
})

代码中处理了异常,但是存在问题:

在多处代码处理异常

没有使用Express的异常处理模块来统一处理异常

接下来,我们来一步步优化代码异常处理。

Express异常处理中间件

所有Express的路由处理函数都有第三个参数next,它可以用来调用下一个中间件,也可以将错误传递给错误处理中间件:

app.get("/users/:id", (req, res, next) => {
  const userId = req.params.id
  if (!userId) {
    const error = new Error("missing id")
    error.httpStatusCode = 400
    return next(error)
  }

  Users.get(userId, (err, user) => {
    if (err) {
      err.httpStatusCode = 500
      return next(err)
    }

    res.send(users)
  })
})

使用next(err),Express就知道出错了,并把这个错误传递给错误处理模块。为了处理这些错误,需要添加一个中间件,它有4个参数:

app.use((err, req, res, next) => {
  // log the error...
  res.sendStatus(err.httpStatusCode).json(err)
})

这样,我们就可以使用中间件统一处理错误了。但是,现在的代码有些重复:创建错误,指定HTTP状态码,使用next(err)...

Fundebug是全栈JavaScript错误监控平台,支持各种前端和后端框架,可以帮助您第一时间发现BUG!

boom

boom是一个兼容HTTP的错误对象,他提供了一些标准的HTTP错误,比如400(参数错误)等。

const boom = require("boom")
app.get("/users/:id", (req, res, next) => {
  const userId = req.params.id
  if (!userId) {
    return next(boom.badRequest("missing id"))
  }

  Users.get(userId, (err, user) => {
    if (err) {
      return next(boom.badImplementation(err))
    }

    res.send(users)
  })
})

错误处理中间件需要稍作修改:

app.use((err, req, res, next) => {
  if (err.isServer) {
    // log the error...
    // probably you don"t want to log unauthorized access
    // or do you?
  }
  return res.status(err.output.statusCode).json(err.output.payload);
})
Async/Await错误处理

使用Async/Await之后,可以这样处理Express异常:

将中间件使用Promise封装起来,使用catch统一处理异常

在中间件中,直接抛出异常就可以了

const boom = require("boom");
// wrapper for our async route handlers
// probably you want to move it to a new file
const asyncMiddleware = fn => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch((err) => {
    if (!err.isBoom) {
      return next(boom.badImplementation(err));
    }
    next(err);
  });
};
// the async route handler
app.get("/users/:id", asyncMiddleware(async (req, res) => {
  const userId = req.params.id
  if (!userId) {
    throw boom.badRequest("missing id")
  }

  const user = await Users.get(userId)
  res.json(user)
}))
参考

验证HTTP请求参数可以使用joi模块

打印日志可以使用winston或者pino模块

版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/12/06/handle-express-error/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90461.html

相关文章

  • js错误处权威指北

    摘要:第一个是,是你传递给异常的构造函数的参数,比如你可以使用属性来访问到该消息第二个参数是异常堆栈跟踪,非常重要。异常产生后能在后端正确处理是的关键部分。我将向你展示自定义构造函数和错误代码的方法,我们可以轻松地将其传递给前端或任何调用者。 By Lukas Gisder-Dubé | nov 14, 2018 原文 接着我上一篇文章,我想谈谈异常。我肯定你之前也听过——异常是个好东西。一...

    lykops 评论0 收藏0
  • 何处 PHP 的错误与异常(笔记)

    摘要:又或者反过来,把错误当成异常来处理。当然,我猜它的目的,应该也是为了能实现错误与异常之间优雅转换而添加的。至此,错误与异常的学习基本完毕。 这话题已经没有什么新意了,这里只是做做笔记,作为思路的一种整理,也以便后续忘了可以回来这里查找。 错误 以下是 PHP 最常见的几种错误: // E_NOTICE echo $a; // E_WARNING echo 100 / 0; clas...

    kyanag 评论0 收藏0
  • Java编程基础20——异常&IO(File类)

    摘要:异常异常的概述和分类异常的概述异常就是程序在运行过程中出现的错误。运行时异常就是程序员所犯的错误,需要回来修改代码。获取异常类名和异常信息,返回字符串。如果路径名不同,就是改名并剪切。删除注意事项中的删除不走回收站。 1_异常(异常的概述和分类) A:异常的概述 异常就是Java程序在运行过程中出现的错误。 B:异常的分类 通过API查看Throwable Error 服务...

    church 评论0 收藏0
  • 前端培训-初级阶段-场景实战(2019-05-30)-input 搜索何防抖,何处中文输入

    摘要:在掘金摸鱼的时候看到了一个题第题搜索如何防抖,如何处理中文输入,感觉挺有意思的。测试地址事件输入法事件输入法的第一个字母时触发。输入法状态输入内容。输入法选择之后触发。 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我...

    Yuanf 评论0 收藏0
  • 前端培训-初级阶段-场景实战(2019-05-30)-input 搜索何防抖,何处中文输入

    摘要:在掘金摸鱼的时候看到了一个题第题搜索如何防抖,如何处理中文输入,感觉挺有意思的。测试地址事件输入法事件输入法的第一个字母时触发。输入法状态输入内容。输入法选择之后触发。 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我...

    BDEEFE 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<