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 相关文章推荐
用XMLDOM和ADODB.Stream实现base64编码解码实现代码
Nov 28 Javascript
javascript 基础篇1 什么是js 建立第一个js程序
Mar 14 Javascript
在js(jquery)中获得文本框焦点和失去焦点的方法
Dec 04 Javascript
jquery根据td给相同tr下其他td赋值的实现方法
Oct 05 Javascript
jQuery删除当前节点元素
Dec 07 Javascript
详解在Angularjs中ui-sref和$state.go如何传递参数
Apr 24 Javascript
JS中的三个循环小结
Jun 20 Javascript
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
Oct 15 Javascript
基于Vue开发数字输入框组件
Dec 19 Javascript
JS中的回调函数实例浅析
Mar 21 Javascript
详解JavaScript匿名函数和闭包
Jul 10 Javascript
vue键盘事件点击事件加native操作
Jul 27 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
Laravel框架模型的创建及模型对数据操作示例
2019/05/07 PHP
javascript基本语法分析说明
2008/06/15 Javascript
Jquery和JS用外部变量获取Ajax返回的参数值的方法实例(超简单)
2013/06/17 Javascript
JavaScript语言核心数据类型和变量使用介绍
2013/08/23 Javascript
网页防止tab键的使用快速解决方法
2013/11/07 Javascript
JavaScript中常见的字符串操作函数及用法汇总
2015/05/04 Javascript
jQuery插件制作之参数用法实例分析
2015/06/01 Javascript
浅谈JS正则表达式的RegExp对象和括号的使用
2016/07/28 Javascript
jQuery使用deferreds串行多个ajax请求
2016/08/22 Javascript
node.js报错:Cannot find module 'ejs'的解决办法
2016/12/14 Javascript
JavaScript实现自动跳转文本功能
2017/05/25 Javascript
Vue实现点击后文字变色切换方法
2018/02/11 Javascript
vue-cli3.0 特性解读
2018/04/22 Javascript
Node.js 使用AngularJS的方法示例
2018/05/11 Javascript
微信小程序HTTP接口请求封装代码实例
2019/09/05 Javascript
VSCode写vue项目一键生成.vue模版,修改定义其他模板的方法
2020/04/17 Javascript
python装饰器使用方法实例
2013/11/21 Python
Python编程入门之Hello World的三种实现方式
2015/11/13 Python
pandas全表查询定位某个值所在行列的方法
2018/04/12 Python
Python实现的质因式分解算法示例
2018/05/03 Python
TensorFlow利用saver保存和提取参数的实例
2018/07/26 Python
Django使用Jinja2模板引擎的示例代码
2019/08/09 Python
python 实现多维数组(array)排序
2020/02/28 Python
Python列表切片常用操作实例解析
2020/03/10 Python
python 实现两个线程交替执行
2020/05/02 Python
Python使用文件操作实现一个XX信息管理系统的示例
2020/07/02 Python
详解CSS3 弹性布局快速入门
2019/06/06 HTML / CSS
html+css实现自定义图片上传按钮功能
2019/09/04 HTML / CSS
请用Java实现列出某个目录下的所有文件
2013/09/23 面试题
电气工程及其自动化自我评价四篇
2013/09/24 职场文书
机电专业求职信
2014/06/14 职场文书
出纳工作检讨书范文
2014/12/27 职场文书
小孩不笨观后感
2015/06/03 职场文书
叶问观后感
2015/06/15 职场文书
师德师风心得体会(2016精选篇)
2016/01/12 职场文书
postgreSQL数据库基础知识介绍
2022/04/12 PostgreSQL