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
jQuery实战之品牌展示列表效果
Apr 10 Javascript
js动态创建、删除表格示例代码
Aug 07 Javascript
js 去掉空格实例 Trim() LTrim() RTrim()
Jan 07 Javascript
JavaScript利用构造函数和原型的方式模拟C#类的功能
Mar 06 Javascript
Jquery实现侧边栏跟随滚动条固定(兼容IE6)
Apr 02 Javascript
我的Node.js学习之路(二)NPM模块管理
Jul 06 Javascript
jQuery EasyUI之DataGrid使用实例详解
Jan 04 Javascript
一种基于浏览器的自动小票机打印实现方案(js版)
Jul 26 Javascript
在node.js中怎么屏蔽掉favicon.ico的请求
Mar 01 Javascript
微信小程序 共用变量值的实现
Jul 12 Javascript
vue脚手架项目创建步骤详解
Mar 02 Vue.js
详解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源代码
2006/10/09 PHP
php SQL防注入代码集合
2008/04/25 PHP
php生成图形验证码几种方法小结
2013/08/15 PHP
typecho插件编写教程(二):写一个新插件
2015/05/28 PHP
OAuth认证协议中的HMACSHA1加密算法(实例)
2017/10/25 PHP
PHP进阶学习之命名空间基本用法分析
2019/06/18 PHP
表单内同名元素的控制
2006/11/22 Javascript
js控制滚动条缓慢滚动到顶部实现代码
2013/03/20 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
2014/01/07 Javascript
vue+ElementUI实现订单页动态添加产品数据效果实例代码
2017/07/13 Javascript
jQuery仿移动端支付宝键盘的实现代码
2018/08/15 jQuery
解决微信小程序防止无法回到主页的问题
2018/09/28 Javascript
vue从一个页面跳转到另一个页面并携带参数的解决方法
2019/08/12 Javascript
微信小程序开发中var that =this的用法详解
2020/01/18 Javascript
JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】
2020/05/01 Javascript
vue v-model的用法解析
2020/10/19 Javascript
把项目从Python2.x移植到Python3.x的经验总结
2015/04/20 Python
Python中使用ElementTree解析XML示例
2015/06/02 Python
python实用代码片段收集贴
2015/06/03 Python
python3 http提交json参数并获取返回值的方法
2018/12/19 Python
Python面向对象程序设计示例小结
2019/01/30 Python
Python实现PyPDF2处理PDF文件的方法示例
2019/09/25 Python
Python使用matplotlib 模块scatter方法画散点图示例
2019/09/27 Python
flask框架json数据的拿取和返回操作示例
2019/11/28 Python
python怎么对数字进行过滤
2020/07/05 Python
pytorch 多分类问题,计算百分比操作
2020/07/09 Python
Python+OpenCV检测灯光亮点的实现方法
2020/11/02 Python
使用canvas一步步实现图片打码功能的方法
2019/06/17 HTML / CSS
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
英国的潮牌鞋履服饰商店:size?
2019/03/26 全球购物
英语专业大学生求职简历的自我评价
2013/10/18 职场文书
我读书我快乐演讲稿
2014/05/07 职场文书
单位作风建设自查报告
2014/10/23 职场文书
计划生育工作总结2015
2015/04/03 职场文书
房屋租赁意向书范本
2015/05/09 职场文书
小学体育组工作总结
2015/08/13 职场文书