best practice of implement exception filter for microservice architecture in Nestjs

260 Views Asked by At

I have Microservice including Gateway ,Users ,Auth

the communicate each other via RabbitMQ

for Exception filter I have used two filter

first is :

import { ArgumentsHost, Catch, HttpException } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';
import { throwError } from 'rxjs';

@Catch()
export class RPCExceptionFilter extends BaseRpcExceptionFilter {
    override catch(exception: unknown, host: ArgumentsHost) {
        return throwError(() => exception);
    }
}

I have used above exception filter for Auth and Users

and the second is :


import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus } from '@nestjs/common';
import { Request, Response } from 'express';
import { TypeORMError } from 'typeorm';
import { PostgresError } from 'postgres'
import { AxiosError } from 'axios'
import { IResponseError } from '../interfaces/error-response.interface';

@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    let message = (exception as any)?.message;
    let code: string = (exception as any)?.response?.error || 'Exception';
    let status: number = (exception as any)?.response?.statusCode || HttpStatus.INTERNAL_SERVER_ERROR;

    const ec = exception
    if (ec instanceof HttpException) {
      status = (exception as HttpException).getStatus();
      message = (exception as any).getResponse()?.message ? (exception as any)?.getResponse().message : (exception as any).getResponse()
      code = (exception as HttpException).message
    }
    else if (ec instanceof TypeORMError) {
      status = HttpStatus.UNPROCESSABLE_ENTITY
      message = (exception as TypeORMError).message;
      code = (exception as TypeORMError).name;
    }
    else if (ec instanceof PostgresError) {
      status = HttpStatus.UNPROCESSABLE_ENTITY
      message = (exception as PostgresError).message;
      code = (exception as PostgresError).code as string;
    }
    else if (ec instanceof AxiosError) {
      status = (exception as AxiosError)?.response?.status || (exception as AxiosError)?.status || 500
      message = (exception as AxiosError)?.message;
      code = (exception as AxiosError)?.code as string;
    }
    response.status(status).json(globalResponseError(status, message, code, request));
  }
}



export const globalResponseError: (statusCode: number, message: string, code: string, request: Request) => IResponseError = (
  statusCode: number,
  message: string,
  code: string,
  request: Request
): IResponseError => {
  return {
    statusCode: statusCode,
    message,
    code,
    timestamp: new Date().toISOString(),
    path: request.url,
    method: request.method
  };
};



and I have used this one for gateway .

and it works fine

I want to know if this approach is good enough ?

and if there is any better one ?

0

There are 0 best solutions below