Next.js Discord

Discord Forum

Intermittent failure on Api route handler persisting data to Prisma

Unanswered
Pip gall wasp posted this in #help-forum
Open in Discord
Pip gall waspOP
Hi folks,

I'm having trouble with an intermittent failure in an api route that is trying to save data to Prisma.

My issue is that I can't reproduce the failure locally and it only seems to happen at certain times on my app hosted on Vercel.

My main issue right now is that I can't event catch and log the error correctly - the function just fails out and doesn't seem to hit my catch block.

I'm new to NextJS / the Node ecosystem, previously was a Rails person so this is all new to me.

any tips on isolating the issue / debugging would be really helpful

2 Replies

Pip gall waspOP
The error I'm seeing is the following:
{"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"TypeError: fetch failed","reason":{"errorType":"TypeError","errorMessage":"fetch failed","cause":{"errorType":"Error","errorMessage":"write ETIMEDOUT","code":"ETIMEDOUT","errno":-110,"syscall":"write","stack":["Error: write ETIMEDOUT","    at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:94:16)","    at WriteWrap.callbackTrampoline (node:internal/async_hooks:130:17)","    at writevGeneric (node:internal/stream_base_commons:138:26)","    at Socket._writeGeneric (node:net:929:11)","    at Socket._writev (node:net:938:8)","    at doWrite (node:internal/streams/writable:409:12)","    at clearBuffer (node:internal/streams/writable:564:5)","    at Writable.uncork (node:internal/streams/writable:351:7)","    at AsyncWriter.write (node:internal/deps/undici/undici:10320:16)","    at writeIterable (node:internal/deps/undici/undici:10259:23)"]},"stack":["TypeError: fetch failed","    at Object.fetch (node:internal/deps/undici/undici:11576:11)"]},"promise":{},"stack":["Runtime.UnhandledPromiseRejection: TypeError: fetch failed","    at process.<anonymous> (file:///var/runtime/index.mjs:1250:17)","    at process.emit (node:events:526:35)","    at emit (node:internal/process/promises:149:20)","    at processPromiseRejections (node:internal/process/promises:283:27)","    at process.processTicksAndRejections (node:internal/process/task_queues:96:32)"]}
The code for the route in question is:
export async function POST(request: Request) {
  const prisma = new PrismaClient();
  const { userId: clerkId, orgId } = auth();
  if (!clerkId) {
    return new NextResponse('Unauthorized', { status: 401 });
  }

  const { scenarioId, transcript } = await request.json();

  console.log('Creating role play for: ', scenarioId);

  try {
    const rolePlay = await prisma.rolePlay.create({
      data: {
        scenario: {
          connect: {
            id: scenarioId,
          },
        },
        transcript,
        user: {
          connect: {
            clerkId: clerkId,
          },
        },
        workspace: {
          connect: {
            clerkId: orgId,
          },
        },
      },
      include: {
        scenario: true,
      },
    });

    console.log('Role Play Created: ', rolePlay.id);

    // call rails to enqueue the feedback
    trackServerEvent({
      eventName: 'role-play-created',
      clerkId,
      properties: {
        orgId,
      },
    });

    const response = await fetch(
      `${process.env.NEXT_PUBLIC_API_URL}/webhooks/enqueue_role_play`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          role_play: {
            id: rolePlay.id,
            scenario: {
              id: rolePlay.scenario.id,
              name: rolePlay.scenario.name,
              description: rolePlay.scenario.description,
              hiddenContext: rolePlay.scenario.hiddenContext,
              format: 'meddpicc',
            },
            transcript: rolePlay.transcript,
          },
        }),
      }
    );

    return NextResponse.json(rolePlay);
  } catch (error) {
    console.log(error);
    return new NextResponse('Internal Server Error', { status: 500 });
  }
}