Am using a global Exception filter with a logger:(WINSTON), that catch all most every Error, including MongoDB error's, Don't know whether it's up to the standard but works for me, I followed Nest Js Doc with some of my custom needs!
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
HttpStatus,
Inject,
LoggerService,
} from '@nestjs/common';
import { Response } from 'express';
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
@Catch()
export class HttpExceptionFilter implements ExceptionFilter {
constructor(
@Inject(WINSTON_MODULE_NEST_PROVIDER)
private readonly logger: LoggerService,
) {}
catch(exp: any, host: ArgumentsHost) {
console.log(exp);
this.logger.error(exp);
const context = host.switchToHttp();
const response = context.getResponse<Response>();
const request = context.getRequest<Request>();
const hasKey = Object.keys(exp).length > 0 && exp.hasOwnProperty('response') ? true : false;
const isHttpInstance = exp instanceof HttpException ? true : false;
const validErrors = hasKey && Array.isArray(exp.response.message) ? exp.response.message : [];
const statusCode = isHttpInstance ? exp.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;
const type = hasKey && exp.response.type ? exp.response.type : 'some_thing_went_error';
const message = isHttpInstance ? exp.message : 'Oops Something went wrong!';
const error = hasKey ? exp.response.error : exp;
response.status(statusCode).json({
message,
type,
validationErrors: validErrors,
statusCode,
error,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
This will be the response be like on MongoDB Error:
{
"message": "Oops Something went wrong!",
"type": "some_thing_went_error",
"validationErrors": [],
"statusCode": 500,
"error": {
"errors": {
"subRegion": {
"name": "ValidatorError",
"message": "Path `subRegion` is required.",
"properties": {
"message": "Path `subRegion` is required.",
"type": "required",
"path": "subRegion"
},
"kind": "required",
"path": "subRegion"
}
},
"_message": "ServiceRequest validation failed",
"name": "ValidationError",
"message": "ServiceRequest validation failed: subRegion: Path `subRegion` is required."
},
"timestamp": "2022-02-08T07:43:35.962Z",
"path": "/v1/service-request"
}
This will be the response be like on Normal Error:
{
"message": "Bad Request Exception",
"type": "some_thing_went_error",
"validationErrors": [
"isEmergency must be one of the following values: true, false",
"isEmergency must be a string",
"isEmergency should not be empty"
],
"statusCode": 400,
"error": "Bad Request",
"timestamp": "2022-02-08T07:47:25.183Z",
"path": "/v1/service-request"
}
If you want the type to be a custom one, that can be thrown from the application you can use the below code
throw new HttpException(
{
status: HttpStatus.FORBIDDEN,
type: 'otp_verification_error',
message: 'Please verify your mobile number to complete the signUp process!',
},
HttpStatus.FORBIDDEN,
);