NestJS 在抛出错误后阻止新请求
NestJS blocking new requests after throwing error
我有一个带有 AppControler
和 AppService
的小型测试应用程序(测试实验室),AppController
有一个 GET
端点并发送请求负载到 AppService
,它有两个异步方法。
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 时,第二个方法将检查该条件(如果为真)并抛出错误。
我习惯于在实际用例中使用异常过滤器来执行此操作,但在这种非常特殊的情况下,每当我调用控制器的端点并且在我的 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<void>
return 类型,但是如果 validateErrorHandling 抛出一个错误,一切都应该停止并且 console.log('TESTING', payload)
不应该被执行(就像它是业务逻辑)。
恐怕不仅仅是我傻,我可能真的遗漏了一些东西。
我们抛出错误的原因是我们想告诉前端应用程序出了问题。为了实现这一点,最好抛出 HTTP 错误而不是简单地抛出它。所以这是代码:
throw new UnprocessableEntityException({
errorCode: UpdateProductErrorStatusEnum.DeviceNotReported,
message: UpdateProductErrorMsgEnum.DeviceNotReported,
});
你有两个选择。首先在服务本身中抛出错误,其次抛出一个错误(就像你所做的那样)并在控制器层中捕获它。每种方式都有自己的优点和缺点。加入控制器会更好,因为控制器旨在处理与 HTTP 相关的内容,而服务仅为逻辑内容创建。但是把controller丢进去,controller就乱了,说不定你的代码就不干净了。
查看此处了解更多信息:https://docs.nestjs.com/exception-filters
我有一个带有 AppControler
和 AppService
的小型测试应用程序(测试实验室),AppController
有一个 GET
端点并发送请求负载到 AppService
,它有两个异步方法。
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 时,第二个方法将检查该条件(如果为真)并抛出错误。
我习惯于在实际用例中使用异常过滤器来执行此操作,但在这种非常特殊的情况下,每当我调用控制器的端点并且在我的 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<void>
return 类型,但是如果 validateErrorHandling 抛出一个错误,一切都应该停止并且 console.log('TESTING', payload)
不应该被执行(就像它是业务逻辑)。
恐怕不仅仅是我傻,我可能真的遗漏了一些东西。
我们抛出错误的原因是我们想告诉前端应用程序出了问题。为了实现这一点,最好抛出 HTTP 错误而不是简单地抛出它。所以这是代码:
throw new UnprocessableEntityException({
errorCode: UpdateProductErrorStatusEnum.DeviceNotReported,
message: UpdateProductErrorMsgEnum.DeviceNotReported,
});
你有两个选择。首先在服务本身中抛出错误,其次抛出一个错误(就像你所做的那样)并在控制器层中捕获它。每种方式都有自己的优点和缺点。加入控制器会更好,因为控制器旨在处理与 HTTP 相关的内容,而服务仅为逻辑内容创建。但是把controller丢进去,controller就乱了,说不定你的代码就不干净了。
查看此处了解更多信息:https://docs.nestjs.com/exception-filters