Prisma 中文文档 下载 App

错误处理:Prisma Client 错误码 P2000~P2034 速查

三类错误

Prisma Client 的错误分三大类,每类有不同的前缀和语义:

错误码范围类别含义
P1xxx数据库连接错误Prisma 连不上数据库
P2xxx已知请求错误Prisma Client 能识别的业务层错误(记录不存在、唯一冲突等)
P3xxxPrisma 引擎内部错误引擎崩溃、超时等底层问题
P4xxxPrisma Migrate 错误迁移相关的错误(v7 起拆分)

P2xxx 业务错误(最常见)

核心错误码速查

错误码含义典型场景HTTP 对应
P2002唯一约束冲突创建 User 时 email 已存在400 / 409
P2025记录不存在findUnique / update / delete 找不到记录404
P2003外键约束失败Post.authorId 指向的 User 不存在400
P2014关系违规——因外键不能删尝试删 User 但他有关联的 Post409
P2011必填字段缺失创建 Post 时没传 title 且它没有默认值400
P2012必填关系字段缺失创建 Post 时没传 author 关系400
P2028事务查询数超限交互事务里发送了太多查询400
P2034事务失败(死锁/写冲突)并发事务互相等待409(应该重试)

处理示例

import { Prisma } from '@prisma/client'

try {
  await prisma.user.create({
    data: { email: 'alice@prisma.io', name: 'Alice' },
  })
} catch (err) {
  if (err instanceof Prisma.PrismaClientKnownRequestError) {
    switch (err.code) {
      case 'P2002':
        // 从 err.meta.target 可以拿到冲突的字段名
        const field = err.meta?.target as string[] | undefined
        console.log(`唯一冲突:${field?.join(', ')}`)
        break
      case 'P2025':
        console.log('记录不存在')
        break
      case 'P2003':
        console.log('外键约束失败')
        break
    }
  } else if (err instanceof Prisma.PrismaClientValidationError) {
    // Schema 校验错误——查询参数和 Schema 对不上
    console.log('参数格式错误')
  }
}

P1xxx 连接错误(排查数据库)

错误码含义
P1001连不上数据库服务器(DNS 解析失败、超时、防火墙)
P1002数据库服务器响应超时(通常是连接池满了或服务器负载高)
P1003数据库指定的目录不存在(SQLite 常见)
P1008操作超时(比如迁移时 lock 等待超时)
P1017数据库服务器已关闭连接
P1020SSL 连接需要但没配(Serverless 平台常见)

P1001 排查步骤

# 1. 用 prisma 自带的 doctor 检查
npx prisma doctor

# 2. 直接 ping 数据库
# PostgreSQL:
psql "postgresql://user:pass@host:5432/dbname"
# MySQL:
mysql -h host -u user -p dbname

Prisma 错误类型层级

Error
├── Prisma.PrismaClientKnownRequestError    ← 有明确错误码的业务错误(P2xxx)
├── Prisma.PrismaClientValidationError      ← 参数校验错误(Schema 不匹配)
├── Prisma.PrismaClientInitializationError  ← 初始化失败(P1xxx 连接错误)
└── Prisma.PrismaClientRustPanicError       ← 引擎崩溃(P3xxx,极其罕见)

类型守卫

用 instanceof 区分不同类型:

catch (err) {
  if (err instanceof Prisma.PrismaClientKnownRequestError) {
    // 有 code 属性,处理 P2xxx
  } else if (err instanceof Prisma.PrismaClientValidationError) {
    // 参数格式问题
  } else {
    // 其他未知错误
    console.error(err)
  }
}

生产环境错误处理策略

  1. 统一 PrismaError 过滤器(参考 NestJS 里的做法)
  2. P2002 映射为 400 Bad Request(告诉前端哪个字段重复)
  3. P2025 映射为 404 Not Found
  4. P2034 用循环重试(指数退避)
  5. P1xxx 记录详细日志并返回 503 Service Unavailable——数据库连不上是运维问题
  6. 永远不要 把原始 Prisma 错误对象的完整信息返回给客户端(可能含数据库结构)