- Published on
Microservices and Custom exception filter in NestJS
- Authors
- Name
- Saad Bash
- Nest offers a default exceptions layer to handle unhandled exceptions in an application. Global microservice exception filters aren't enabled by default when using a hybrid application.
- In the case of an error occurring on a microservice, it is recommended to use
RpcException
instead ofHttpException
. - To catch RpcException on the client side, implementing "Exception filters" is a good practice. These filters offer greater control over the flow of the application and allow customization of the response returned to the client from the microservice.
To create a custom exception filter, extend the RpcException
:
import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common'
import { RpcException } from '@nestjs/microservices'
@Catch(RpcException)
export class IIRpcExceptionFilter implements ExceptionFilter {
catch(exception: RpcException, host: ArgumentsHost) {
const ctx = host.switchToHttp()
const error: any = exception.getError()
const response = ctx.getResponse()
const message = exception.message
// Customize the error response as desired
response.status(error.status).json({
status: error.status,
message: message,
error: 'CustomException',
})
}
}
Use the @UseFilters()
decorator to apply the filter to the controller or method you want to handle the RpcException error:
import { Controller, Get, UseFilters } from '@nestjs/common'
import { IRpcExceptionFilter } from './rpc-exception.filter'
import { AppService } from './app.service'
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
@UseFilters(IRpcExceptionFilter)
async getHello(): Promise<string> {
return this.appService.getHello()
}
}
To use the
RpcException
filter globally: main.tsimport { NestFactory } from '@nestjs/core' import { AppModule } from './app.module' import { IRpcExceptionFilter } from './rpc-exception.filter' async function bootstrap() { const app = await NestFactory.create(AppModule) // Add Global Filter in main.ts app.useGlobalFilters(new IRpcExceptionFilter()) await app.listen(3000) } bootstrap()
In the microservice client, throw an RpcException
with the appropriate status code and message when an error occurs:
import { Controller } from '@nestjs/common'
import { MessagePattern, RpcException } from '@nestjs/microservices'
@Controller()
export class AppController {
@MessagePattern({ cmd: 'getHello' })
async getHello(): Promise<string> {
try {
// ... some code that might throw an error
} catch (error) {
throw new RpcException({
message: error,
status: HttpStatus.BAD_REQUEST,
})
}
}
}
With these steps, we have created a custom exception filter that handles RpcException errors thrown by a microservice in NestJS.