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 相关文章推荐
js电信网通双线自动选择技巧
Nov 18 Javascript
DOM 基本方法
Jul 18 Javascript
javaScript Array(数组)相关方法简述
Jul 25 Javascript
33种Javascript 表格排序控件收集
Dec 03 Javascript
深入理解javascript变量声明
Nov 20 Javascript
jQuery中on()方法用法实例详解
Feb 06 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖放商品放置购物车
Nov 30 Javascript
微信小程序 教程之事件
Oct 18 Javascript
VUE页面中加载外部HTML的示例代码
Sep 20 Javascript
浅谈Vue数据绑定的原理
Jan 08 Javascript
JavaScript实现仿Clock ISO时钟
Jun 29 Javascript
利用js实现简单开关灯代码
Nov 23 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
15种PHP Encoder的比较
2007/03/06 PHP
PHP反向代理类代码
2014/08/15 PHP
php中fsockopen用法实例
2015/01/05 PHP
PHP记录搜索引擎蜘蛛访问网站足迹的方法
2015/04/15 PHP
用js实现的页面关键字密度查询代码
2007/12/27 Javascript
jquery 插件开发备注
2010/08/27 Javascript
jquery图片延迟加载 前端开发技能必备系列
2012/06/18 Javascript
Javascript实现重力弹跳拖拽运动效果示例
2013/06/28 Javascript
浅谈Javascript中Object与Function对象
2015/09/26 Javascript
浅谈js的url解析函数封装
2016/06/28 Javascript
JS时间控制实现动态效果的实例讲解
2017/07/31 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
2018/01/05 Javascript
JavaScript+Canvas实现彩色图片转换成黑白图片的方法分析
2018/07/31 Javascript
jQuery的Ajax接收java返回数据方法
2018/08/11 jQuery
vue实现后台管理权限系统及顶栏三级菜单显示功能
2019/06/19 Javascript
js实现GIF图片的分解和合成
2019/10/24 Javascript
JavaScript字符串处理常见操作方法小结
2019/11/15 Javascript
python的re模块应用实例
2014/09/26 Python
利用Psyco提升Python运行速度
2014/12/24 Python
在Python的一段程序中如何使用多次事件循环详解
2017/09/07 Python
Python paramiko模块的使用示例
2018/04/11 Python
django进阶之cookie和session的使用示例
2018/08/17 Python
设置python3为默认python的方法
2018/10/31 Python
Anaconda3+tensorflow2.0.0+PyCharm安装与环境搭建(图文)
2020/02/18 Python
python 使用cycle构造无限循环迭代器
2020/12/02 Python
加拿大领先的牛仔零售商:Bluenotes
2018/01/22 全球购物
教堂婚礼主持词
2014/03/14 职场文书
社区平安建设方案
2014/05/25 职场文书
新闻人物通讯稿
2014/10/09 职场文书
行政复议决定书
2015/06/24 职场文书
大学班干部竞选稿
2015/11/20 职场文书
《平行四边形的面积》教学反思
2016/02/16 职场文书
《我要的是葫芦》教学反思
2016/02/18 职场文书
一文搞懂如何实现Go 超时控制
2021/03/30 Python
jquery插件实现图片悬浮
2021/04/16 jQuery
Python列表的索引与切片
2022/04/07 Python