【问题标题】:NestJS blocking new requests after throwing errorNestJS在抛出错误后阻止新请求
【发布时间】:2022-02-03 21:35:29
【问题描述】:

我有一个带有AppControlerAppService 的小型测试应用程序(测试实验室),AppController 有一个GET 端点并将请求有效负载发送到AppService,它有两个异步方法.

应用服务

async requestTesting (payload): Promise<void> { // This is what's being called from the controller
    
  if(payload) {
      await this.validateErrorHandling(payload)
  }

  console.log('TESTING', payload)

// DO STUFF

}

async validateErrorHandling(payload): Promise<void> {
     console.log('DO STUFF')

  if(payload && payload.number > 2) { // This is true
     throw new Error()
  }

}

当 requestTesting 调用 validateErrorHandling 时,第二种方法将检查该条件(如果为真)并抛出错误。 我习惯于在实际用例中使用异常过滤器来执行此操作,但在这种非常特殊的情况下,每当我调用 Controller 的端点并且在我的 AppService 上抛出该错误时,都会显示以下内容:

UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "........".

在我重新启动应用程序之前,我无法通过邮递员发出任何其他请求。 邮递员表演:

Error: connect ECONNREFUSED 127.0.0.1:3000

现在,我知道 try/catch 应该可以解决此问题,但我试图了解为什么这会停止我的整个应用程序而不是仅停止函数执行,因为它以前从未发生在我身上,如果我试着把它扔到其他任何地方,它就可以了。

现在,这两个方法都有一个Promise&lt;void&gt; 返回类型,但是如果 validateErrorHandling 抛出一个错误,一切都应该停止并且不应该执行 console.log('TESTING', payload)(就像它是业务逻辑一样)。 恐怕不仅仅是我傻了,我可能真的错过了什么。

【问题讨论】:

  • 你可能忘记了一些await,留下了浮动的承诺。当你的控制器的方法被调用时,检查所有的承诺
  • 这就是让我感动的部分,我省略了方法名称和其他逻辑测试(仅在其中使用 console.log()),但一切正常。另外,如果我在控制器中抛出错误,它不会停止整个应用程序,尽管这应该只是表明我确实遗漏了一些东西,但我没有发现任何异常
  • 能不能也展示一下控制器的功能?

标签: javascript node.js typescript error-handling nestjs


【解决方案1】:

我们抛出错误的原因是我们想告诉前端应用程序出错了。为了实现这一点,最好抛出一个 HTTP 错误而不是简单地抛出它。所以这里是代码:

throw new UnprocessableEntityException({
  errorCode: UpdateProductErrorStatusEnum.DeviceNotReported,
  message: UpdateProductErrorMsgEnum.DeviceNotReported,
});

你有两个选择。首先在服务本身中抛出错误,其次抛出错误(就像你所做的那样)并在控制器层中捕获它。每种方式都有其优点和缺点。加入控制器会更好,因为控制器旨在处理与 HTTP 相关的内容,并且仅为逻辑内容创建服务。但是把控制器扔进去会让控制器乱七八糟,可能你的代码也不会干净。

查看这里了解更多信息:https://docs.nestjs.com/exception-filters

【讨论】:

  • 感谢您的回答,但这并没有回答我的问题。我习惯于使用基于 Nest 全局异常过滤器制作的自定义异常过滤器库来处理 NestJS 上的错误。在特定情况下抛出错误后,NestJS 会阻塞(或停止)应用程序,这很奇怪。不过还是谢谢你!编辑:另外,我不同意只抛出“告诉前端应用程序出了问题”的错误,它也可能用于后端应用程序
  • 您的异常过滤器(如果它与nestjs 带来的相同)将仅捕获HTTP 异常。因此,当您throw Error() 时,您应该手动捕获它。关于你的最后一句话,是的,后端也使用了抛出错误。例如,您有一个在 npm 上发布的模块,然后例如,如果您做错了什么,该包会抛出一个错误(因为他们不想让您走得更远)并且您应该通过捕获来正确处理它它。
  • 因此,总而言之,无论您出于前端还是后端内部目的抛出错误,您都应该抛出基于 HTTP 的错误(对于前端情况)或手动抛出并捕获它(出于后端目的)
  • 啊,我不得不重新阅读你的答案,我一定是累了,误解了你的答案,对不起。无论如何...如果我需要根据业务逻辑抛出不同的错误怎么办?我可能会创建一个自定义过滤器来捕获各种错误(这就是我提到的过滤器所做的),这将使我的控制器再次清洁,对吗?但如果出于某种原因我不想在控制器上捕获错误?
  • 另外,“抛出服务”和“抛出错误并在控制器上捕获它”是什么意思?我把它扔在服务上。
猜你喜欢
  • 2020-12-17
  • 2023-01-03
  • 1970-01-01
  • 2012-03-20
  • 2018-02-21
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 2020-12-12
相关资源
最近更新 更多