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 相关文章推荐
用Juery网页选项卡实现代码
Jun 13 Javascript
限制textbox或textarea输入字符长度的JS代码
Oct 16 Javascript
jQuery动态改变图片显示大小(修改版)的实现思路及代码
Dec 24 Javascript
AngularJS入门教程之学习环境搭建
Dec 06 Javascript
基于jQuery实现网页进度显示插件
Mar 04 Javascript
jquery+html仿翻页相册功能
Dec 20 Javascript
jquery与js实现全选功能的区别
Jun 11 jQuery
全面解析jQuery中的$(window)与$(document)的用法区别
Aug 15 jQuery
bootstrap Table的一些小操作
Nov 01 Javascript
Vue.js 图标选择组件实践详解
Dec 03 Javascript
JavaScript实现美化滑块效果
May 17 Javascript
浅谈javascript错误处理
Aug 11 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提取字符串中的图片地址[正则表达式]
2011/11/12 PHP
一个PHP的ZIP压缩类分享
2014/05/04 PHP
PHP实现动态获取函数参数的方法示例
2018/04/02 PHP
JavaScript入门教程(9) Document文档对象
2009/01/31 Javascript
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
JavaScript Array对象扩展indexOf()方法
2014/05/09 Javascript
JQuery实现动态添加删除评论的方法
2015/05/18 Javascript
JQuery+Ajax实现数据查询、排序和分页功能
2015/09/27 Javascript
js判断checkbox是否选中个数的方法(超简单)
2016/08/19 Javascript
懒加载实现的分页&&网站footer自适应
2016/12/21 Javascript
jQuery基本筛选选择器实例代码
2017/02/06 Javascript
Bootstrap布局之栅格系统学习笔记
2017/05/04 Javascript
微信小程序 开发之全局配置
2017/05/05 Javascript
基于JS实现网页中的选项卡(两种方法)
2017/06/16 Javascript
mui 打开新窗口的方式总结及注意事项
2017/08/20 Javascript
EasyUI框架 使用Ajax提交注册信息的实现代码
2017/09/27 Javascript
Vue用v-for给src属性赋值的方法
2018/03/03 Javascript
小程序点赞收藏功能的实现代码示例
2018/09/07 Javascript
微信小程序实现星级评价
2019/11/20 Javascript
[52:36]VGJ.S vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python 字符串定义
2009/09/25 Python
用Python的Django框架来制作一个RSS阅读器
2015/07/22 Python
Win7下搭建python开发环境图文教程(安装Python、pip、解释器)
2016/05/17 Python
深入解析Python中的__builtins__内建对象
2016/06/21 Python
解决pyqt中ui编译成窗体.py中文乱码的问题
2016/12/23 Python
详解使用python绘制混淆矩阵(confusion_matrix)
2019/07/14 Python
Python中 CSV格式清洗与转换的实例代码
2019/08/29 Python
css3个性化字体_动力节点Java学院整理
2017/07/12 HTML / CSS
纯CSS3大转盘抽奖示例代码(响应式、可配置)
2017/01/13 HTML / CSS
HTML5中的进度条progress元素简介及兼容性处理
2016/06/02 HTML / CSS
HTML5新特性之语义化标签
2017/10/31 HTML / CSS
Sandro Paris美国官网:典雅别致的法国时尚服饰品牌
2017/12/26 全球购物
加拿大专业美发产品购物网站:Chatters
2021/02/28 全球购物
材料加工硕士生求职信
2013/10/10 职场文书
2014年医学生毕业自我鉴定
2014/03/26 职场文书
车队安全员岗位职责
2015/02/15 职场文书