Prismaのユニーク制約に対するエラーハンドリング方法

はじめに

こんにちは、株式会社TOKOSのツキヤです!
今回はややニッチ? な内容を記述します💪

DB側でusersテーブルのemailカラムはユニーク値にしたい場合は割とあるあるなケースかと思います!
Prismaを使っている場合に、そのユニーク制約のエラーをキャッチ(ハンドリング)する方法です!

対象読者・前提

  • Prismaを使用している方
  • ユニーク制約のバリデーションを設けたい方

スキーマは下記の様なものを想定しています!

model User {
  id            Int      @id @default(autoincrement())
  name          String
  email         String   @unique
  @@map("users")
}

スキーマに関して詳しい解説が欲しい方は以下の記事を参考にしてください💪

Prismaでのスキーマの様々な記述方法解説!

エラーハンドリング方法

早速ですが、方法を書きます!

// ...

try {
  prisma.user.create({
    // paramsにはフロントから来たそれぞれの値が入っている
    name: params.name
    email: params.email
  })
} catch(error) {
  // ユニーク制約のエラー処理
  if (error instanceof Prisma.PrismaClientKnownRequestError) {
    if (error.code === "P2002") {
      return {
        message: "このメールアドレスは既に使われています",
        ok: false,
      }
    }
  }
}

Prismaは、ユニーク制約等でのDB側の都合でcreateができなかった場合も例外をthrowします!
そのエラーオブジェクトは基本的にPrisma.PrismaClientKnownRequestErrorとなります。
なので、11行目でまず想定内のエラーかどうかを確認しています。

そして、error.codeの値でどのようなエラーかが決まっています!
"P2002"は「ユニーク制約のエラー」とPrisma側が決めてくれています✨
よって、error.code === "P2002"で比較をして、trueの場合はその旨を記載したバリデーションエラーメッセージを返してあげることで利用ユーザーに分かりやすくエラー内容を伝えることができます💪

おわりに

error.codeの値について、他にも色々あるので基本的にやりたいことはできるはずです!
値一覧については下記公式ドキュメントを参考にしてみてください✨