【问题标题】:How to handle errors in async Express?如何处理异步 Express 中的错误?
【发布时间】:2020-11-25 05:59:53
【问题描述】:

背景:我有一个相当大的项目,它是一个社交媒体后端。我们在 JS 中使用 MondoDB (w/mongoose) 和 Express。我的问题是:是否有必要继续将每条路由包装在 try/catch 块中以确保响应?目前几乎我们的所有路线(有些需要返回更具体的错误)如下所示:

router.get('/path/to/route', async (req, res, next) => {
    try {
        // function of route
    } catch (err) {
        res.status(500).send({ status: false })
    }
}

我怀疑在每条路线上持续使用try/catch使用async 函数可能存在一些反模式。我的想法是简单地制作一个发送 500 响应的标准错误处理程序,但是我相信 try/catch 仍然需要使用 next(err)

总体:

  • 我们的代码是反模式的吗?
  • 路由应该使用异步吗?
  • 应该继续使用try/catch 块吗?
  • 正确的模式是什么?

如果有人有时间回复,非常感谢。

【问题讨论】:

    标签: javascript node.js mongodb express asynchronous


    【解决方案1】:

    您不应该在每条路线上都使用try/catch。您可以使用中间件来捕获处理所有错误并使用适当的状态代码进行响应。一个简短的例子是:

    app.use(function (err, req, res, next) {
      console.error(err.stack)
      res.status(500).send({ status: false })
    })
    

    您可以在 Express here 中阅读有关错误处理的更多信息

    【讨论】:

      【解决方案2】:

      我建议使用这些内容在您的项目中创建一个 errorHandler.js 文件。

      class ErrorHandler extends Error {
        constructor(statusCode, message) {
          super();
          this.statusCode = statusCode;
          this.message = message;
        }
      }
      
      
       const handleError = (err, res) => {
        const { statusCode, message } = err;
        res.status(statusCode).json({
          status: "error",
          statusCode,
          message
        });
      };
      
      module.exports = {
        ErrorHandler, 
        handleError
      }
      

      然后在你的 api.index.js 中注册一个中间件,在导入你的 errorHandler.js 文件的导出成员之后,就像这样。

      import {handleError} from errorHandler.js;
      
      app.use((err, req, res, next) => {
        handleError(err, res);
      });
      

      然后每次要处理潜在错误时,从 ErrorHandler.js 文件中导入 ErrorHandler 类,然后简单地使用此签名

      import {ErrorHandler} from errorHandler.js;
      
      if(somethingWentAwry){
           throw new ErrorHandler(400, "something went really awry")
       }
      

      由于 handleError 函数,以及它在 api.index.js 中作为中间件的使用,没有处理 next,所以当你抛出错误时,链就结束了。

      该解决方案的灵感来自于 Chinedu Orie 的帖子 here

      【讨论】:

      • 仅链接的答案是不可取的。您应该从链接页面中提取核心解决方案。如果您唯一要做的就是引用,请确保将其放置在引用块内。这样人们就知道你不是自己写的(否则你会因为抄袭而被否决),然后在你的答案中的某处添加对原始阅读材料的引用。提取有用信息的原因是因为如果链接断开,答案就不会成立。如果您不想投入工作而只想留下链接,请改用评论。
      • @3limin4t0r 感谢您的意见。我已经相应地更新了答案。
      猜你喜欢
      • 2015-04-15
      • 2015-07-18
      • 2019-03-21
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      相关资源
      最近更新 更多