Skip to content

Instantly share code, notes, and snippets.

@gsusmonzon
Last active August 21, 2024 10:40
Show Gist options
  • Save gsusmonzon/ecd7842495f07594761e40c2758617d0 to your computer and use it in GitHub Desktop.
Save gsusmonzon/ecd7842495f07594761e40c2758617d0 to your computer and use it in GitHub Desktop.
Make NestJs returns 404 when EntityNotFoundError exception is thrown

Make NestJs returns 404 when EntityNotFoundError exception is thrown

When using findOrFail() or findOneOrFail() from typeORM, a 500 error is returned if there is no entity (EntityNotFoundError).

To make it returns a 404, use an exception filter as described in https://docs.nestjs.com/exception-filters .

file /src/filters/entity-not-found-exception.filter.ts

import { Catch, ExceptionFilter, ArgumentsHost} from "@nestjs/common";
import { EntityNotFoundError } from 'typeorm/error/EntityNotFoundError'
import { Response } from 'express';


/**
 * Custom exception filter to convert EntityNotFoundError from TypeOrm to NestJs responses
 * @see also @https://docs.nestjs.com/exception-filters
 */
@Catch(EntityNotFoundError, Error)
export class EntityNotFoundExceptionFilter implements ExceptionFilter {
  public catch(exception: EntityNotFoundError, host: ArgumentsHost) {

    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    return response.status(404).json({ message: { statusCode: 404, error: 'Not Found', message: exception.message } });
  }
}

Use it in your main module

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { EntityNotFoundExceptionFilter } from './filters/entity-not-found-exception.filter';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new EntityNotFoundExceptionFilter());
  await app.listen(3000);
}
bootstrap();
@lakmalniranga
Copy link

Really helpful thanks!

@marchrius
Copy link

Great! IMHO catching a generic Error is not a good choice.

@crrmacarse
Copy link

Be careful by including Error in the catch. This will include exception thrown by others(such as class-validator) to be formatted.

This should be EntityNotFoundError only as it focuses with typeorm

@gsusmonzon
Copy link
Author

@marchrius , @crrmacarse you are right
in fact reviewing my current code, i am using only @Catch(EntityNotFoundError)
I guess i did a mistake when editing this gist

@Wangenye
Copy link

Wangenye commented Jun 6, 2022

Great..Really useful!

@achepukov
Copy link

Thanks lot! You made my day! :)

@Wangenye
Copy link

Wangenye commented Jul 1, 2023

Now you can also use one form nestjs/common

throw new NotFoundException()

@RockYou-cmd
Copy link

@Wangenye thank you so much

@micobarac
Copy link

import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpStatus,
} from '@nestjs/common';
import { Request, Response } from 'express';
import {
  CannotCreateEntityIdMapError,
  EntityNotFoundError,
  QueryFailedError,
} from 'typeorm';

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

    switch (exception.constructor) {
      case QueryFailedError:
        status = HttpStatus.BAD_REQUEST;
        message = (exception as QueryFailedError).message;
        code = (exception as any).code;
        break;
      case EntityNotFoundError:
        status = HttpStatus.NOT_FOUND;
        message = (exception as EntityNotFoundError).message;
        code = (exception as any).code;
        break;
      case CannotCreateEntityIdMapError:
        status = HttpStatus.UNPROCESSABLE_ENTITY;
        message = (exception as CannotCreateEntityIdMapError).message;
        code = (exception as any).code;
        break;
      default:
        status = (exception as any).status;
        message = (exception as any).message.message;
        code = (exception as any).code;
        break;
    }

    response.status(status).json({
      statusCode: status,
      message,
      code,
      timestamp: new Date().toISOString(),
      path: request.url,
      method: request.method,
    });
  }
}

@micobarac
Copy link

micobarac commented Aug 21, 2024

Add cases of specific TypeORMError or any other error that needs special treatment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment