首页 > 语言 > JavaScript > 正文

NodeJS处理Express中异步错误

2024-05-06 15:19:21
字体:
来源:转载
供稿:网友

摘要

比起回调函数,使用 Promise 来处理异步错误要显得优雅许多。

结合 Express 内置的错误处理机制和 Promise 极大地降低产生未捕获错误(uncaught exception)的可能性。

Promise 在ES6中是默认选项。如果使用 Babel 转译,它也可以与 Generators 或者 Async/Await 相结合。

本文主要阐述如何在 Express 中使用错误处理中间件(error-handling middleware)来高效处理异步错误。在 Github 上有对应 代码实例 可供参考。

首先,让我们一起了解 Express 提供的开箱即用的错误处理工具。然后,我们将探讨如何使用 Promise, Generators 以及 ES7 的 async/await 来简化错误处理流程。

Express 内置的异步错误处理

在默认情况下,Express 会捕获所有在路由处理函数中的抛出的异常,然后将它传给下一个错误处理中间件:

app.get('/', function (req, res) { throw new Error('oh no!')})app.use(function (err, req, res, next) { console.log(err.message) // 噢!不!})

对于同步执行的代码,以上的处理已经足够简单。然而,当异步程序在执行时抛出异常的情况,Express 就无能为力。原因在于当你的程序开始执行回调函数时,它原来的栈信息已经丢失。

app.get('/', function (req, res) { queryDb(function (er, data) {  if (er) throw er })})app.use(function (err, req, res, next) { // 这里拿不到错误信息})

对于这种情况,可以使用 next 函数来将错误传递给下一个错误处理中间件

app.get('/', function (req, res, next) { queryDb(function (err, data) {  if (err) return next(err)  // 处理数据  makeCsv(data, function (err, csv) {   if (err) return next(err)   // 处理 csv  }) })})app.use(function (err, req, res, next) { // 处理错误})

使用这种方法虽然一时爽,却带来了两个问题:

你需要显式地在错误处理中间件中分别处理不同的异常。

一些隐式异常并没有被处理(如尝试获取一个对象并不存在的属性)

利用 Promise 传递异步错误

在异步执行的程序中使用 Promise 处理任何显式或隐式的异常情况,只需要在 Promise 链尾加上 .catch(next) 即可。

app.get('/', function (req, res, next) { // do some sync stuff queryDb()  .then(function (data) {   // 处理数据   return makeCsv(data)  })  .then(function (csv) {   // 处理 csv  })  .catch(next)})app.use(function (err, req, res, next) { // 处理错误})

现在,所有异步和同步程序都将被传递到错误处理中间件。棒棒的。

虽然 Promise 让异步错误的传递变得容易,但这样的代码仍然有一些冗长和刻板。这时候 promise generator 就派上了用场。

用 Generators 简化代码

如果你使用的环境原生支持 Generators,你可以手动实现以下的功能。不过这里我们将借用 Bluebird.coroutine 来说明如何使用 Promise generator 来简化刚才的代码。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选