express异步函数异常捕获示例详解


Posted in Javascript onNovember 30, 2020

在express中时使用 Async/await 编写异步代码时,每个 async 函数都要包裹在try/catch中,代码量多了看着冗余不优雅,express又不像koa的异步机制可以订阅全局的error事件,为了解决这个问题,需要写个捕获异步函数异常的中间件。

uncaughtException

开始能想到的肯定是try/catch了,但是也想过能否使用nodejs提供的uncaughtException事件,在全局捕获异常,例如下面的代码:

process.on("uncaughtException", (err) => console.log("uncaught Exception"));

const asyncError=()=>{
 throw new Error("some Error");
}

asyncError();

asyncError方法里面抛出的异常会被 uncaughtException订阅,但是在异步函数中,并没走到 uncaughtException,还是会抛出异常:

process.on("uncaughtException", (err) => console.log("uncaught Exception"));

const asyncError=()=>{
 throw new Error("some Error");
}

(async ()=>{
 // 抛出异常
 asyncError();
})()

而且Promise.reject也没走到uncaughtException里面:

const asyncError=()=>{
 return Promise.reject("some error")
}

(async ()=>{
 // 抛出异常
 await asyncError();
})()

所以在express中使用nodejs提供的uncaughtException处理异步错误不太合适,一方面没法捕获和定位上下文错误,另一方面也没法将错误异常提供给中间件函数处理

解决思路

要处理express中的异步函数错误,最好的方法当然是编写处理异常的中间件了,try/catch开路,包裹中间件方法,catch到的异常直接交给next函数处理,代码如下:

const asyncHandler = fn =>{
 return (req,res,next)=>{
  try{
   fn(req,res,next)
  }catch(next)
 }
}
module.exports = asyncHandler;

接下来,在异步函数中引入中间件处理:

app.use(asyncHandler(async(req, res, next) => {
 await authenticate(req);
 next();
}));

app.get('/async', asyncHandler(async(req, res) => {
 const result = await request('http://example.com');
 res.end(result);
}));

使用asyncHandler方法包裹的async/await函数,如果出现错误就会被Error-handling中间件捕获了

但是每次用到异步函数的时候都要包裹asyncHandler方法,真正用起来也不是很爽,这里推荐使用express-async-errors中间件,其原理是将express里面的中间全部包裹上一层asyncHandler方法,让错误异常无所遁形,全部跑到Error-handling中间件。

前提是引入express后,先引入express-async-errors方法:

const express = require('express');
require('express-async-errors');
const User = require('./models/user');
const app = express();

app.get('/users', async (req, res) => {
 const users = await User.findAll();
 res.send(users);
});

接下来的在异步函数中,就不用都包裹上try/catch了,有错误提前throw Error,写起代码来美滋滋:

app.use(async (req, res) => {
 const user = await User.findByToken(req.get('authorization'));

 if (!user) throw Error("access denied");
});

app.use((err, req, res, next) => {
 if (err.message === 'access denied') {
 res.status(403);
 res.json({ error: err.message });
 }

 next(err);
});~~~~

参考链接:

  • Using Async/await in Express
  • Handling errors in express async middleware

到此这篇关于express异步函数异常捕获示例的文章就介绍到这了,更多相关express异步函数异常捕获内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript 可以拖动的DIV(二)
Jun 26 Javascript
图片轮换效果实现代码(点击按钮停止执行)
Apr 12 Javascript
jquery统计输入文字的个数并对其进行判断
Jan 07 Javascript
JQuery 控制内容长度超出规定长度显示省略号
May 23 Javascript
Js与Jq 获取页面元素值的方法和差异对比
Apr 30 Javascript
Jquery注册事件实现方法
May 18 Javascript
jquery实现从数组移除指定的值
Jun 24 Javascript
开发一个Parcel-vue脚手架工具(详细步骤)
Sep 22 Javascript
Vue formData实现图片上传
Aug 20 Javascript
jquery获取并修改触发事件的DOM元素示例【基于target 属性】
Oct 10 jQuery
原生JS实现汇率转换功能代码实例
May 13 Javascript
OpenLayers3实现图层控件功能
Sep 25 Javascript
详解Vue 的异常处理机制
Nov 30 #Vue.js
ESLint 是如何检查 .vue 文件的
Nov 30 #Vue.js
JavaScript实现商品评价五星好评
Nov 30 #Javascript
详解React路由传参方法汇总记录
Nov 29 #Javascript
基于jQuery拖拽事件的封装
Nov 29 #jQuery
原生js+canvas实现验证码
Nov 29 #Javascript
原生js实现弹幕效果
Nov 29 #Javascript
You might like
深入PHP运行环境配置的详解
2013/06/04 PHP
php生成数组的使用示例 php全组合算法
2014/01/16 PHP
Nginx实现反向代理
2017/09/20 Servers
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
用js自动判断浏览器分辨率的代码
2007/01/28 Javascript
jQuery live( type, fn ) 委派事件实现
2009/10/11 Javascript
Firefox+FireBug使JQuery的学习更加轻松愉快
2010/01/01 Javascript
js读写(删除)Cookie实例详解
2013/04/17 Javascript
js文件缓存之版本管理详解
2013/07/05 Javascript
详细解读AngularJS中的表单验证编程
2015/06/19 Javascript
JavaScript 性能优化小结
2015/10/12 Javascript
js实现简单计算器
2015/11/22 Javascript
jQuery简单动画变换效果实例分析
2016/07/04 Javascript
javascript+css3开发打气球小游戏完整代码
2017/11/28 Javascript
基于vue-cli 打包时抽离项目相关配置文件详解
2018/03/07 Javascript
VuePress 快速踩坑小结
2019/02/14 Javascript
layui--js控制switch的切换方法
2019/09/03 Javascript
[01:32:50]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第一场 1月25日
2021/03/11 DOTA
python类继承用法实例分析
2014/10/10 Python
简单介绍Python中的try和finally和with方法
2015/05/05 Python
python树莓派红外反射传感器
2019/01/21 Python
python三方库之requests的快速上手
2019/03/04 Python
Python Numpy数组扩展repeat和tile使用实例解析
2019/12/09 Python
html5+svg学习指南之SVG基础知识
2014/12/17 HTML / CSS
巴西在线鞋店:Shoestock
2017/10/28 全球购物
Viking Direct爱尔兰:办公用品和家具
2019/11/21 全球购物
女大学生自我鉴定
2013/12/09 职场文书
关于礼仪的演讲稿
2014/01/04 职场文书
单位工程竣工验收方案
2014/03/16 职场文书
卖车协议书范本4篇
2014/10/01 职场文书
九九重阳节标语
2014/10/07 职场文书
国庆节慰问信
2015/02/15 职场文书
质量保证书怎么写
2015/02/27 职场文书
民事辩护词范文
2015/05/21 职场文书
想要创业,那么你做好准备了吗?
2019/07/01 职场文书
什么是css原子化,有什么用?
2022/04/24 HTML / CSS