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利用与或运算符优先级实现if else条件判断表达式
Apr 15 Javascript
在js(jquery)中获得文本框焦点和失去焦点的方法
Dec 04 Javascript
Jquery实现自定义窗口随意的拖拽
Mar 12 Javascript
深入探密Javascript数组方法
Jan 08 Javascript
JS模式之简单的订阅者和发布者模式完整实例
Jun 30 Javascript
jquery validate demo 基础
Oct 29 Javascript
jQuery自定义滚动条完整实例
Jan 08 Javascript
JavaScript 定时器 SetTimeout之定时刷新窗口和关闭窗口(代码超简单)
Feb 26 Javascript
jQuery javascript获得网页的高度与宽度的实现代码
Apr 26 Javascript
简单谈谈vue的过渡动画(推荐)
Oct 11 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(下)
Apr 18 Javascript
JavaScript实现五子棋游戏的方法详解
Jul 08 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
浅析ThinkPHP中execute和query方法的区别
2014/06/13 PHP
JQuery.uploadify 上传文件插件的使用详解 for ASP.NET
2010/01/22 Javascript
Extjs 几个方法的讨论
2010/01/28 Javascript
IE与FireFox的JavaScript兼容问题解决办法
2013/12/31 Javascript
详解jQuery UI库中文本输入自动补全功能的用法
2016/04/23 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
微信小程序 wx.request(OBJECT)发起请求详解
2016/10/13 Javascript
图片懒加载插件实例分享(含解析)
2017/01/09 Javascript
javascript实现秒表计时器的制作方法
2017/02/16 Javascript
详解angularjs中如何实现控制器和指令之间交互
2017/05/31 Javascript
Angular浏览器插件Batarang介绍及使用
2018/02/07 Javascript
如何使用Javascript中的this关键字
2020/05/28 Javascript
JavaScript函数柯里化实现原理及过程
2020/12/02 Javascript
[00:32]10月24、25日 辉夜杯外卡赛附加赛开赛!
2015/10/23 DOTA
[01:19:46]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第一场 2月28日
2021/03/11 DOTA
python3使用urllib模块制作网络爬虫
2016/04/08 Python
python实现读取excel写入mysql的小工具详解
2017/11/20 Python
Python实现基本数据结构中栈的操作示例
2017/12/04 Python
Python中Numpy包的安装与使用方法简明教程
2018/07/03 Python
解决pandas中读取中文名称的csv文件报错的问题
2018/07/04 Python
pytorch 共享参数的示例
2019/08/17 Python
Python 实现毫秒级淘宝抢购脚本的示例代码
2019/09/16 Python
python字符串判断密码强弱
2020/03/18 Python
利用Python发送邮件或发带附件的邮件
2020/11/12 Python
Python第三方库安装缓慢的解决方法
2021/02/06 Python
HTML5之SVG 2D入门4—笔画与填充
2013/01/30 HTML / CSS
本科生学习总结的自我评价
2013/10/02 职场文书
工业自动化专业毕业生推荐信
2013/11/18 职场文书
餐饮部总监岗位职责范文
2014/02/13 职场文书
商学院大学生求职的自我评价
2014/03/12 职场文书
婚前协议书怎么写
2014/04/15 职场文书
班级学习雷锋活动总结
2014/07/04 职场文书
股东授权委托书范文
2014/09/13 职场文书
2014年行政执法工作总结
2014/12/11 职场文书
python绘制箱型图
2021/04/27 Python
游戏《我的世界》澄清Xbox版暂无计划加入光追
2022/04/03 其他游戏