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 相关文章推荐
jQuery 渐变下拉菜单
Dec 15 Javascript
线路分流自动智能跳转代码,自动选择最快镜像网站(js)
Oct 31 Javascript
在jQuery中 关于json空对象筛选替换
Apr 15 Javascript
javascript-简单的计算器实现步骤分解(附图)
May 30 Javascript
javascript实现的一个随机点名功能
Aug 26 Javascript
一个简单的动态加载js和css的jquery代码
Sep 01 Javascript
JS实现滑动菜单效果代码(包括Tab,选项卡,横向等效果)
Sep 24 Javascript
ionic 上拉菜单(ActionSheet)实例代码
Jun 06 Javascript
在网页中插入百度地图的步骤详解
Dec 02 Javascript
详解vue.js之绑定class和style的示例代码
Aug 24 Javascript
electron-vue开发环境内存泄漏问题汇总
Oct 10 Javascript
JavaScript实现简单随机点名器
Nov 21 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
把从SQL中取出的数据转化成XMl格式
2006/10/09 PHP
基于PHP导出Excel的小经验 完美解决乱码问题
2013/06/10 PHP
PHP整合PayPal支付
2015/06/11 PHP
使用xampp搭建运行php虚拟主机的详细步骤
2015/10/21 PHP
Zend Framework框架教程之Zend_Db_Table_Rowset用法实例分析
2016/03/21 PHP
Zend Framework实现将session存储在memcache中的方法
2016/03/22 PHP
jquery-easyui关闭tab自动切换到前一个tab
2010/07/29 Javascript
初学js 新节点的创建 删除 的步骤
2011/07/04 Javascript
JavaScript window.document的属性、方法和事件小结
2012/10/24 Javascript
jquery制作多功能轮播图插件
2015/04/02 Javascript
Kindeditor单独调用多图上传实例
2017/07/31 Javascript
react实现一个优雅的图片占位模块组件详解
2017/10/30 Javascript
使用Angular9和TypeScript开发RPG游戏的方法
2020/03/25 Javascript
JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
2020/04/13 Javascript
原生JS实现音乐播放器
2021/01/26 Javascript
[00:36]DOTA2上海特级锦标赛 LGD战队宣传片
2016/03/04 DOTA
python插入排序算法实例分析
2015/07/03 Python
python3新特性函数注释Function Annotations用法分析
2016/07/28 Python
Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】
2017/09/28 Python
python PyTorch参数初始化和Finetune
2018/02/11 Python
python互斥锁、加锁、同步机制、异步通信知识总结
2018/02/11 Python
pycharm安装和首次使用教程
2018/08/27 Python
python GUI库图形界面开发之PyQt5打开保存对话框QFileDialog详细使用方法与实例
2020/02/27 Python
英国著名书店:Foyles
2018/12/01 全球购物
几个SQL的面试题
2014/03/08 面试题
2019年.net常见面试问题
2012/02/12 面试题
C#如何调用Windows程序打开一个文档
2014/12/26 面试题
程序员岗位职责
2013/11/11 职场文书
质量承诺书范文
2014/03/27 职场文书
留学生求职信
2014/06/03 职场文书
安全横幅标语
2014/06/09 职场文书
会计专业自荐书
2014/07/08 职场文书
“四风”问题自我剖析材料思想汇报
2014/09/23 职场文书
求职简历自我评价2015
2015/03/10 职场文书
飞越疯人院观后感
2015/06/09 职场文书
面试提问mysql一张表到底能存多少数据
2022/03/13 MySQL