如何处理Express异常?
2017-12-26 20:57
232 查看
译者按:根据墨菲定律:“有可能出错的事情,就会出错”。那么,既然代码必然会出错,我们就应该处理好异常。
原文: How to handle errors in Express
译者:Fundebug
为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。
处理异常是编程非常重要的一点。我们的程序依赖于第三方服务、数据库以及我们的用户,一切都不可预料。数据库可能会宕机,第三方服务可能会崩溃,用户可能会使用错误的参数调用我们的接口。
为了处理各种复杂的情况,我们必须处理好代码异常,下面是代码示例:
代码中处理了异常,但是存在问题:
- 在多处代码处理异常
- 没有使用Express的异常处理模块来统一处理异常
接下来,我们来一步步优化代码异常处理。
使用next(err),Express就知道出错了,并把这个错误传递给错误处理模块。为了处理这些错误,需要添加一个中间件,它有4个参数:
这样,我们就可以使用中间件统一处理错误了。但是,现在的代码有些重复:创建错误,指定HTTP状态码,使用next(err)…
Fundebug是全栈JavaScript错误监控平台,支持各种前端和后端框架,可以帮助您第一时间发现BUG!
错误处理中间件需要稍作修改:
将中间件使用Promise封装起来,使用catch统一处理异常
在中间件中,直接抛出异常就可以了
打印日志可以使用winston或者pino模块
版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/12/06/handle-express-error/
原文: 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/
相关文章推荐
- 如何处理Express异常?
- 如何处理Java异常的两个例子?
- 当在Appdomain中发生未处理异常时如何不让程序结束掉
- java开发中,大家处理异常的原则是什么,是如何处理的?
- 如何在shell中处理异常(Part 2)
- 各种异常产生原因及如何处理解决
- 如何在shell中处理异常(Part 1)
- 1 异常的概述和体系结构: jvm处理异常的方式和try。。。Catch处理异常:异常的抛出:如何处理多个异常:Throwable的常用的方法:异常的分类 自定义异常:
- 代码中的异常如何处理【未解决】
- C++编译器如何实现异常处理
- 如何解决未经处理的win32异常
- 如何捕获和处理逃出线程外的异常
- Lua是如何处理错误异常问题的(1)?
- try ,finally都抛出异常如何处理.如果try中抛出了异常,在控制权转移到调用栈上一层代码之前, finally 语句块也会执行,如果finally抛出异常,try语句快抛出的那个异常就
- 我在项目中Springmvc处理异常并记录日志(一) ps:如何有更好的方法,请写到评论中多多交流,谢谢!
- java中如果我老是少捕获什么异常,如何处理?
- ARM 处理器如何处理异常
- XEIM 里如何使用 CFileException 处理异常的
- 如何解决“不允许有匹配 "[xX][mM][lL]" 的处理指令目标。”的异常信息。同时提供几个spring xml配置文件标头!(干货)
- 如何金蝶bos处理调试异步队列时发生异常