exceptions: handling errors in the Nest service layer

I would like to create a REST API with NestJs. But I want to add GraphQL as another higher level layer later. So, for starters, I have the basic layer controller, the service and the TypeORM repository. Suppose you want to update a user's username by id. The controller path could be

PATCH /users/:id/username

Two problems may arise in the service or repository layer:

  • User ID may not exist
  • Username already exist

The basic flow of this operation would be

  • Get the user by id
  • Handle error if the user does not exist
  • Check if the username already exists
  • Handle error if username already exists
  • Update the user's username

I'm thinking about how I should handle those mistakes. I could throw exceptions immediately based on this concept

https://en.wikipedia.org/wiki/Fail-fast

NestJs provides some ready-to-use exceptions that I can use

https://docs.nestjs.com/exception-filters#built-in-http-exceptions

The problem is that I don't think I should throw HTTP exceptions in my service layer. They must be thrown into the logic of my controller. So what is a common approach to those mistakes?

  • I must return? undefined instead of an updated user? The controller would not know which part failed.
  • Should I create my own exceptions by extending Error and throw them away?
  • Due to the fact that exceptions come with poor performance if the return type of the function is something like ?