Reputation: 661
I've got a small testing application (a test lab) with an AppControler
and an AppService
, AppController
has a GET
endpoint and send requests payload to AppService
, which has two async methods.
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()
}
}
When requestTesting calls validateErrorHandling, the second method is going to check that condition (if truthy) and shall throw an Error.
I'm used to do this with an exception filter on real use cases, but in this very specific case, whenever I call my Controller's endpoint and that error is thrown on my AppService
, the following is shown:
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 "........".
And I'm unable to make any other request through postman until I restart the app. Postman shows:
Error: connect ECONNREFUSED 127.0.0.1:3000
Now, I'm aware that a try/catch should fix this, but I'm trying to understand why this is stopping my whole application instead of stopping the function execution only, as it never happened to me before, and if I try to throw it anywhere else, it just works.
Now, both methods have a Promise<void>
return type, but if validateErrorHandling throws an error, everything should stop and that console.log('TESTING', payload)
should not be executed (as if it were business logic).
I'm afraid it's not just me being silly, but I might actually be missing something.
Upvotes: 4
Views: 4831
Reputation: 5243
The reason that we throw an error is that we want to tell the front application that something went wrong. In order to achieve this, it's better to throw an HTTP error instead of simply throwing it. So here is the code:
throw new UnprocessableEntityException({
errorCode: UpdateProductErrorStatusEnum.DeviceNotReported,
message: UpdateProductErrorMsgEnum.DeviceNotReported,
});
You have two options. First throw the error in the service itself, second to throw an Error (as you did) and catch it in the controller layer. Each way has its own pros and cons. Throwing in the controller is better because the controller is designed to handle HTTP related stuff, and service is created for only logic stuff. But throwing in the controller makes the controller messy and maybe your code will not be clean.
See here for more info: https://docs.nestjs.com/exception-filters
Upvotes: 2