'What is the correct type of Exception to throw in a Nestjs service?

So, by reading the NestJS documentation, I get the main idea behind how the filters work with exceptions.

But from all the code I have seen, it seems like all services always throw HttpExceptions.

My question is: Should the services really be throwing HttpExceptions? I mean, shouldn't they be more generic? And, if so, what kind of Error/Exception should I throw and how should I implement the filter to catch it, so I won't need to change it later when my service is not invoked by a Http controller?

Thanks :)



Solution 1:[1]

No they should not. An HttpException should be thrown from within a controller. So yes, your services should expose their own errors in a more generic way. But "exposing errors" doesn't have to mean "throwing exceptions".

Let's say you have the following project structure :

? sample
 |_ ? sample.controller.ts
 |_ ? sample.service.ts

When calling one of your SampleService methods, you want your SampleController to know whether or not it should throw an HttpException.

This is where your SampleService comes into play. It is not going to throw anything but it's rather going to return a specific object that will tell your controller what to do.

Consider the two following classes :

export class Error {
  constructor(
    readonly code: number,
    readonly message: string,
  ) {}
}

export class Result<T> {
  constructor(readonly data: T) {}
}

Now take a look at this random SampleService class and how it makes use of them :

@Injectable()
export class SampleService {

  isOddCheck(numberToCheck: number): Error | Result<boolean> {
    const isOdd = numberToCheck%2 === 0;
    if (isOdd) {
      return new Result(isOdd);
    }

    return new Error(
      400,
      `Number ${numberToCheck} is even.`
    );
  }

}

Finally this is how your SampleController should look like :

@Controller()
export class SampleController {
  constructor(
    private readonly sampleService: SampleService
  ) {}

  @Get()
  sampleGetResponse(): boolean {
    const result = this.sampleService.isOddCheck(13);
    if (result instanceof Result) {
      return result.data;
    }
    
    throw new HttpException(
      result.message,
      result.code,
    );
  }

}

As you can see nothing gets thrown from your service. It only exposes whether or not an error has occurred. Only your controller gets the responsibility to throw an HttpException when it needs to.

Also notice that I didn't use any exception filter. I didn't have to. But I hope this helps.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1