notiz-dev / nestjs-prisma

Easy Prisma support for your NestJS application
https://nestjs-prisma.dev
MIT License
572 stars 49 forks source link

support custom error message mappings #73

Closed megane42 closed 10 months ago

megane42 commented 1 year ago

resolves #72

Examples

useGlobalFilters()

// src/main.ts
import { HttpStatus } from '@nestjs/common';
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import { PrismaClientExceptionFilter } from 'nestjs-prisma';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // prisma exception filter
  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(
    new PrismaClientExceptionFilter(
      httpAdapter,
      // Prisma Error Code: HTTP Status Response
      {
        P2000: HttpStatus.BAD_REQUEST,
        P2002: HttpStatus.CONFLICT,
        P2025: HttpStatus.NOT_FOUND,
      },
      // Prisma Error Code: Error Message
      // You can omit some error codes (like P2002 here) so that the default messages are used.
      {
        P2000: 'something went wrong',
        P2025: 'resource not found',
      },
    ),
  );

  await app.listen(3000);
}
bootstrap();

APP_FILTER

// src/app.module.ts
import { HttpStatus, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { APP_FILTER, HttpAdapterHost } from '@nestjs/core';
import { PrismaClientExceptionFilter, PrismaModule } from 'nestjs-prisma';

@Module({
  imports: [PrismaModule.forRoot()],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_FILTER,
      useFactory: ({ httpAdapter }: HttpAdapterHost) => {
        return new PrismaClientExceptionFilter(
          httpAdapter,
          {
            // Prisma Error Code: HTTP Status Response
            P2000: HttpStatus.BAD_REQUEST,
            P2002: HttpStatus.CONFLICT,
            P2025: HttpStatus.NOT_FOUND,
          },
          // Prisma Error Code: Error Message
          // You can omit some error codes (like P2002 here) so that the default messages are used.
          {
            P2000: 'something went wrong',
            P2025: 'resource not found',
          },
        );
      },
      inject: [HttpAdapterHost],
    },
  ],
})
export class AppModule {}

or

// src/app.module.ts
import { HttpStatus, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import {
  PrismaModule,
  providePrismaClientExceptionFilter,
} from 'nestjs-prisma';

@Module({
  imports: [PrismaModule.forRoot()],
  controllers: [AppController],
  providers: [
    AppService,
    providePrismaClientExceptionFilter(
      {
        P2000: HttpStatus.BAD_REQUEST,
        P2002: HttpStatus.CONFLICT,
        P2025: HttpStatus.NOT_FOUND,
      },
      {
        P2000: 'something went wrong',
        P2025: 'resource not found',
      },
    ),
  ],
})
export class AppModule {}

Results

Before

image

After

image

Note

Only status mappings are used for judging whether or not to handle Prisma errors. Message mappings are not used for it. So if the app setting is like this:

      // status mappings
      {
        P2000: HttpStatus.BAD_REQUEST,
      },
      // message mappings
      {
        P2000: 'something went wrong',
        P2028: 'transaction error',
      },

the nest app returns 500 Internal server error when P2028 happens. Note that P2000 P2002 P2025 are always handled implicitly because they are hard-coded.

marcjulian commented 1 year ago

Thanks for the PR @megane42. I like the approach, but it seems that we need to duplicate the status codes to the HttpStatus and again for the message.

What if we could include the custom message in the first object. Just an idea to either set the status or object {status: number, message: string}

app.useGlobalFilters(
    new PrismaClientExceptionFilter(
      httpAdapter,
      // Prisma Error Code: HTTP Status Response
      {
        P2000: HttpStatus.BAD_REQUEST,
        P2002: HttpStatus.CONFLICT,
        P2025: { status: HttpStatus.NOT_FOUND, message: 'Resource not found' }
      }
    ),
  );
megane42 commented 11 months ago

@marcjulian Hi, let me know if there is anything I can do to help merge this PR. Sorry to rush you like this 🙏

marcjulian commented 11 months ago

Hi @megane42, I haven't forgotten about your PR. I will try to find time to review and merge your PR soon.

mohrazzak commented 10 months ago

Thanks for this PR, I really hope to get this finished ASAP because it's really important feature.

Greeting to you Devs.

marcjulian commented 10 months ago

The custom error message can be testet in the latest dev release.

npm i nestjs-prisma@0.23.0-dev.0