You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Next.js路由处理器中打印Prisma错误对象时出现异常

问题:Next.js PUT路由中console.error打印Prisma错误触发新报错的原因

代码示例

export async function PUT(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {    
  try {
    const { id } = await params;
    const body = await request.json();

    const updatedIssue = await prisma.issue.update({
      where: { id: parseInt(id) },
      data: {
        title: body.title,
        description: body.description,
      },
    });
    return NextResponse.json(updatedIssue);
  } catch (error) {
    console.error(error);
    return NextResponse.json(error, { status: 500 });
  }
}

现象描述

当捕获到Prisma客户端错误(如更新不存在的记录)时,调用console.error(error)会抛出新错误:

TypeError: The "payload" argument must be of type object. Received null

此时接口返回500状态码但无响应体。若移除console.error(error)语句,接口会返回正常的错误响应体:

{
    "name": "PrismaClientKnownRequestError",
    "code": "P2025",
    "clientVersion": "6.1.0",
    "meta": {
        "modelName": "Issue",
        "cause": "Record to update not found."
    }
}

若改为console.error(JSON.stringify(error)),则能正常打印错误信息,且接口返回正确的响应体。想请教该现象的原因,是否与Next.js底层封装console有关?


原因分析

这个问题确实和Next.js对console的封装有关,核心是Prisma错误对象的特殊性与Next.js日志处理逻辑的冲突:

  1. Prisma错误对象的特殊结构
    Prisma抛出的PrismaClientKnownRequestError等错误并非普通JS Error实例,它包含大量非枚举属性或内部循环引用。直接传递给console.error时,Next.js的日志序列化逻辑无法正确处理这些特殊结构,最终返回null,触发TypeError。

  2. Next.js对服务器端console的封装
    Next.js在服务器端(App Router路由处理器属于服务器端代码)对console做了封装,用于统一日志格式、对接日志系统。但这个封装逻辑在处理复杂错误对象时,没有做足够的兼容处理——当遇到无法序列化的属性或循环引用时,会直接返回null,导致后续报错。

  3. JSON.stringify的兼容作用
    使用JSON.stringify(error)时,会自动过滤循环引用和非枚举属性,只保留可序列化的核心字段(如name、code、meta)。此时console.error接收的是合法字符串,不会触发序列化异常;同时NextResponse.json(error)能正常处理错误对象的序列化,返回正确响应体。

额外说明:NextResponse.json内部对Error对象做了专门的序列化兼容,但Next.js封装的console.error没有实现同样的逻辑,这才导致了代码中出现的矛盾现象。


内容的提问来源于stack exchange,提问作者4rrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:55:03