express异步函数异常捕获示例详解

在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);
});~~~~

参考链接:

到此这篇关于express异步函数异常捕获示例的文章就介绍到这了,更多相关express异步函数异常捕获内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • NodeJS处理Express中异步错误

    摘要 比起回调函数,使用 Promise 来处理异步错误要显得优雅许多. 结合 Express 内置的错误处理机制和 Promise 极大地降低产生未捕获错误(uncaught exception)的可能性. Promise 在ES6中是默认选项.如果使用 Babel 转译,它也可以与 Generators 或者 Async/Await 相结合. 本文主要阐述如何在 Express 中使用错误处理中间件(error-handling middleware)来高效处理异步错误.在 Github 上

  • Ajax异步文件上传与NodeJS express服务端处理

    为了避免在实现简单的异步文件上传功能时候引入一个第三方库文件的尴尬情形(库文件可能造成多余的开销,拉低应用加载速度,尤其是在引入库文件之后仅使用其中一两个功能的情况下,性价比极低),最近了解了一下文件异步上传的实现原理,顺带看了看进度条.图片预览等功能的实现,做一点简单的整理. 文件上传 HTML结构如下,一个file input和一个button.当点击"上传"按钮的时候,将file input选中的文件上传到服务器. <input type="file"

  • node.js express捕获全局异常的三种方法实例分析

    本文实例讲述了node.js express捕获全局异常的三种方法.分享给大家供大家参考,具体如下: 场景 express的路由里抛出异常后,全局中间件没办法捕获,需要在所有的路由函数里写try catch,这坑爹的逻辑让人每次都要多写n行代码 官方错误捕获中件间代码如下 app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); }); 测

  • 浅谈Express异步进化史

    1.导言 在 Javascript 的世界里,异步(由于JavaScript的单线程运行,所以JavaScript中的异步是可以阻塞的)无处不在. Express 是 node 环境中非常流行的Web服务端框架,有很大比例的 Node Web应用 采用了 Express. 当使用 JavaScript 编写服务端代码时,我们无可避免的会大量使用到异步.随着 JavaScript.Node 的进化,我们的异步处理方式,也就随之进化. 接下来,我们就来看看 Express 中异步处理的进化过程. 2

  • express异步函数异常捕获示例详解

    在express中时使用 Async/await 编写异步代码时,每个 async 函数都要包裹在try/catch中,代码量多了看着冗余不优雅,express又不像koa的异步机制可以订阅全局的error事件,为了解决这个问题,需要写个捕获异步函数异常的中间件. uncaughtException 开始能想到的肯定是try/catch了,但是也想过能否使用nodejs提供的uncaughtException事件,在全局捕获异常,例如下面的代码: process.on("uncaughtExce

  • java异步编程CompletableFuture使用示例详解

    目录 一.简单介绍 二.常见操作 1.使用默认线程池 2.使用自定义线程池 3.获取线程的执行结果 三.处理异步结算的结果 四.异常处理 五.组合 CompletableFuture 六.并行运行多个 CompletableFuture 七.案例 1.从多个平台获取书价格 2.从任意一个平台获取结果就返回 一.简单介绍 CompletableFuture 同时实现了 Future 和 CompletionStage 接口. public class CompletableFuture<T> i

  • PHP日期和时间函数的使用示例详解

    (1)查看日期函数拓展 phpinfo() <?php phpinfo(); 打开上述页面之后,可以看到以下,证明已经安装日期拓展 浏览器输入php.net访问php的文档 (2)设置时区 方式一:修改配置文件php.ini D:\ITSoft\wamp64\bin\php\php7.0.10\php.ini [Date] ; Defines the default timezone used by the date functions ; http://php.net/date.timezon

  • JavaScript函数封装的示例详解

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,

  • JavaScript箭头函数与普通函数的区别示例详解

    目录 箭头函数与普通函数的区别 箭头函数的理解 箭头函数里的this指向 总结 箭头函数与普通函数的区别 要讨论箭头函数和普通函数的区别,首先来看看两者的基本格式 普通函数和箭头共同点就是圆括号和大括号,圆括号里面一般放置参数,大括号一般放置函数主体,很明显箭头函数不需要写那么长,举个例子,有一个数组,使用map方法为数组的每个元素增加字符 let arr=['昨天','今天','明天'] let newarr=arr.map(function(item){ return item+='放假'

  • Swift中的高阶函数功能作用示例详解

    目录 高阶函数的作用 1. 简化代码 2. 提高可读性 3. 支持函数式编程 4. 提高代码的可重用性 常见的高阶函数 1. map() 2. filter() 3. reduce() 4. sorted() 5. forEach() 6. compactMap() 7. flatMap() 8. zip() 9. first() 10. contains() 高阶函数的作用 Swift中的高阶函数是指那些参数或返回值是函数的函数.它们的存在使得我们可以用非常简洁和优雅的代码来解决许多问题. 1

  • Python 异步之推导式示例详解

    目录 引言 1. 什么是异步推导式 2. 推导式 3. 异步推导式 4. Await 推导式 引言 当我们想到“pythonic”时,理解,如列表和字典理解是 Python 的一个特性. 这是我们执行循环的一种方式,与许多其他语言不同. Asyncio 允许我们使用异步推导式. 我们可以通过“async for”表达式使用异步推导式来遍历异步生成器和异步迭代器. 1. 什么是异步推导式 异步推导式是经典推导式的异步版本.Asyncio 支持两种类型的异步推导式,它们是“async for”推导式

  • Android 全局异常捕获实例详解

    Android 全局异常捕获 今天就来说说作为程序猿的我们每天都会遇到的东西bug,出bug不可怕可怕的是没有出bug时的堆栈信息,那么对于bug的信息收集就显得尤为重要了,一般用第三方bugly或者友盟等等都能轻易收集,但是由于公司不让使用第三方,而安卓正好有原生的异常收集类UncaughtExceptionHandler,那么今天博客就从这个类开始. UncaughtExceptionHandler见名知意,即他是处理我们未捕获的异常,具体使用分两步 1.实现我们自己的异常处理类 publi

  • python中异常捕获方法详解

    在Python中处理异常使用的是try-except代码块,try-except代码块放入让python执行的操作,同时告诉python程序如果发生了异常该怎么办,try-except这个功能其实很多入门书籍中都放到了高级篇幅里,在入门的时候一般不会讲这个使用,尤其是作为运维人员,如果你经常写shell,转到python后估计也很少使用这个功能,这功能我觉得说明了shell和python的一个重要区别,因为python是一门真正的编程语言,像其它的编程语言php,java等都会提供异常捕获功能,

  • 在SQL Server中使用 Try Catch 处理异常的示例详解

    目录 如何在 SQL Server 中使用 Try Catch 处理错误? 示例:了解 SQL Server 中的 Try-Catch 实现. 在 SQL Server 中使用 try-catch 的示例 如何在 SQL Server 中使用 Try Catch 处理错误? 从 SQL Server 2005 开始,我们在TRY 和 CATCH块的帮助下提供了结构错误处理机制.使用TRY-CATCH的语法如下所示. BEGIN TRY --这里写可能导致错误的语句 END TRY BEGIN C

随机推荐