NestJs Microservice exception handling

Karolis Ščerbiakas • October 10, 2019

nestjs

Microservices is this concept of breaking up a monolith into a smaller pieces to make project more manageable.

Today's tip is about how to handle errors in NestJs microservice architecture. For an example lets use Redis as a proxy between other microservices instead of letting each microservice talk to each other.
We are using Redis of instead of direct TCP connection for several reasons: it can serve as a cache, and we can utilize PubSub feature.
The main benefit is that microservices are decoupled, meaning it doesn't need to know about each other, don't care how to connect to each other etc. Anyway, who don't use Redis these days?

So let's say you have a math service in your microservice architecture which accumulates numbers.
Errors happen. Exceptions should be thrown. Instead of throwing standard HttpException you have to throw RpcException

Here's an example:

@Injectable()
export class MathService {
  public accumulate(data: number[]): number {
    throw new RpcException(‘An error was thrown’);
  }
}

Math microservice is throwing RpcException. So in your client microservice (where this math microservice will be consumed) you can handle it like this:

@Injectable()
export class MathService {
  private client: ClientProxy;

  constructor() {
    this.client = ClientProxyFactory.create({
      transport: Transport.REDIS,
      options: {
        url: 'redis://localhost:6379',
      },
    });
  }

  public accumulate(data: number[]) {
    return (
      this.client
        // From here we connect to the math microservice.
        // if there is no error it will return a response directly
        // to the browser or other api consumer
        .send<number, number[]>(‘add’, data)
        // if there is an error `catchError` operator will catch it
        // and `of` observable will return observable with your error object
        .pipe(catchError(val => of({ error: val.message })))
    );
  }
}

So if you’re familiar with RxJS you probably already saw that the client returns an observable,
what it essentially means you can apply other operators to your observable stream and modify response to your needs.

Hope this helps!
Have a nice day!
Karolis