😄

nestjs-prismaを使用してエラーハンドリングする

2024/05/07に公開

概要

NestJS/Prismaを使用してREST APIを作成していた際にエラーハンドリングを簡単に行う方法があったので備忘録

結論

nestjs-prismaを使用すればおおまかなエラーハンドリングの対応ができた

前提

nestjs:10.3.2
@prisma/client:5.13.0
nestjs-prisma:0.23.0

Prisma定義

model User {
  id       String @id @default(cuid())
  name     String @unique
}

controller

// user.controller.ts
  @Post()
  async createUser(
    @Body()
    data: {
      id: string,
      name: string
    }
  ): Promise<User> {
    const response = this.userService.createUser(data)
    return response
  }

service

// user.service.ts
  async createUser(data:{id: string, name: string}): Promise<User> {
    const response = await this.prisma.user.create({data})
    return response
  }

上記の場合、userテーブルに既に登録されているnameをリクエストするとPrismaClientKnownRequestErrorとなる

// コンソールエラー抜粋
Unique constraint failed on the fields: (`name`)
PrismaClientKnownRequestError: 

この時レスポンスは500エラーとしてまとめられてしまう

{
  "statusCode": 500,
  "message": "Internal server error"
}

対処手順

  1. nestjs-prismaインストール

  2. ExceptionFilterページを参考にアプリケーションをカスタマイズ

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

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

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new PrismaClientExceptionFilter(httpAdapter));

  await app.listen(3000);
}
bootstrap();
  1. 上記対応後、前提で失敗していたリクエストのレスポンスは以下のようになる
{
  "statusCode": 409,
  "message": "[P2002]: Unique constraint failed on the fields: (`name`)"
}

Prismaクライアントエラーの種別はPxxxx のエラーコードで分類され、エラーコードに応じたstatusCodeとmessageがレスポンスで返される。
https://www.prisma.io/docs/orm/reference/error-reference

公式ドキュメント

nestjs-prisma
参考記事

Discussion