From 619f6e408fc412dca754a64fc9ecfeb5dded31cd Mon Sep 17 00:00:00 2001 From: Piyush Gupta <56182734+gupta-piyush19@users.noreply.github.com> Date: Fri, 27 Jun 2025 18:20:35 +0530 Subject: [PATCH] fix: `/api/v2/management/contact-attribute-keys` returns 500 instead of 409 on duplicate record (#6100) --- .../[contactAttributeKeyId]/lib/contact-attribute-key.ts | 7 +++---- .../lib/tests/contact-attribute-key.test.ts | 7 +++---- .../contact-attribute-keys/lib/contact-attribute-key.ts | 3 +-- .../lib/tests/contact-attribute-key.test.ts | 7 +++---- .../v2/management/responses/[responseId]/lib/display.ts | 4 ++-- .../v2/management/responses/[responseId]/lib/response.ts | 7 +++---- .../responses/[responseId]/lib/tests/display.test.ts | 4 ++-- .../responses/[responseId]/lib/tests/response.test.ts | 6 +++--- .../webhooks/[webhookId]/lib/tests/mocks/webhook.mock.ts | 5 ++--- .../api/v2/management/webhooks/[webhookId]/lib/webhook.ts | 7 +++---- .../[organizationId]/teams/[teamId]/lib/teams.ts | 7 +++---- .../teams/[teamId]/lib/tests/teams.test.ts | 6 +++--- 12 files changed, 31 insertions(+), 39 deletions(-) diff --git a/apps/web/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/lib/contact-attribute-key.ts b/apps/web/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/lib/contact-attribute-key.ts index ccfbc37f9d..f001f8b074 100644 --- a/apps/web/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/lib/contact-attribute-key.ts +++ b/apps/web/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/lib/contact-attribute-key.ts @@ -1,7 +1,6 @@ import { TContactAttributeKeyUpdateSchema } from "@/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/types/contact-attribute-keys"; import { ApiErrorResponseV2 } from "@/modules/api/v2/types/api-error"; -import { ContactAttributeKey } from "@prisma/client"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; +import { ContactAttributeKey, Prisma } from "@prisma/client"; import { cache as reactCache } from "react"; import { prisma } from "@formbricks/database"; import { PrismaErrorType } from "@formbricks/database/types/error"; @@ -55,7 +54,7 @@ export const updateContactAttributeKey = async ( return ok(updatedKey); } catch (error) { - if (error instanceof PrismaClientKnownRequestError) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { if ( error.code === PrismaErrorType.RecordDoesNotExist || error.code === PrismaErrorType.RelatedRecordDoesNotExist @@ -106,7 +105,7 @@ export const deleteContactAttributeKey = async ( return ok(deletedKey); } catch (error) { - if (error instanceof PrismaClientKnownRequestError) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { if ( error.code === PrismaErrorType.RecordDoesNotExist || error.code === PrismaErrorType.RelatedRecordDoesNotExist diff --git a/apps/web/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/lib/tests/contact-attribute-key.test.ts b/apps/web/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/lib/tests/contact-attribute-key.test.ts index 688973cfd5..0b8361dbaf 100644 --- a/apps/web/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/lib/tests/contact-attribute-key.test.ts +++ b/apps/web/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/lib/tests/contact-attribute-key.test.ts @@ -1,6 +1,5 @@ import { TContactAttributeKeyUpdateSchema } from "@/modules/api/v2/management/contact-attribute-keys/[contactAttributeKeyId]/types/contact-attribute-keys"; -import { ContactAttributeKey } from "@prisma/client"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; +import { ContactAttributeKey, Prisma } from "@prisma/client"; import { describe, expect, test, vi } from "vitest"; import { prisma } from "@formbricks/database"; import { PrismaErrorType } from "@formbricks/database/types/error"; @@ -44,12 +43,12 @@ const mockUpdateInput: TContactAttributeKeyUpdateSchema = { description: "User's verified email address", }; -const prismaNotFoundError = new PrismaClientKnownRequestError("Mock error message", { +const prismaNotFoundError = new Prisma.PrismaClientKnownRequestError("Mock error message", { code: PrismaErrorType.RelatedRecordDoesNotExist, clientVersion: "0.0.1", }); -const prismaUniqueConstraintError = new PrismaClientKnownRequestError("Mock error message", { +const prismaUniqueConstraintError = new Prisma.PrismaClientKnownRequestError("Mock error message", { code: PrismaErrorType.UniqueConstraintViolation, clientVersion: "0.0.1", }); diff --git a/apps/web/modules/api/v2/management/contact-attribute-keys/lib/contact-attribute-key.ts b/apps/web/modules/api/v2/management/contact-attribute-keys/lib/contact-attribute-key.ts index 3193aa0a62..fb09bcb952 100644 --- a/apps/web/modules/api/v2/management/contact-attribute-keys/lib/contact-attribute-key.ts +++ b/apps/web/modules/api/v2/management/contact-attribute-keys/lib/contact-attribute-key.ts @@ -5,7 +5,6 @@ import { } from "@/modules/api/v2/management/contact-attribute-keys/types/contact-attribute-keys"; import { ApiErrorResponseV2 } from "@/modules/api/v2/types/api-error"; import { ContactAttributeKey, Prisma } from "@prisma/client"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; import { cache as reactCache } from "react"; import { prisma } from "@formbricks/database"; import { PrismaErrorType } from "@formbricks/database/types/error"; @@ -58,7 +57,7 @@ export const createContactAttributeKey = async ( return ok(createdContactAttributeKey); } catch (error) { - if (error instanceof PrismaClientKnownRequestError) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { if ( error.code === PrismaErrorType.RecordDoesNotExist || error.code === PrismaErrorType.RelatedRecordDoesNotExist diff --git a/apps/web/modules/api/v2/management/contact-attribute-keys/lib/tests/contact-attribute-key.test.ts b/apps/web/modules/api/v2/management/contact-attribute-keys/lib/tests/contact-attribute-key.test.ts index 748329f155..455d09afb7 100644 --- a/apps/web/modules/api/v2/management/contact-attribute-keys/lib/tests/contact-attribute-key.test.ts +++ b/apps/web/modules/api/v2/management/contact-attribute-keys/lib/tests/contact-attribute-key.test.ts @@ -2,8 +2,7 @@ import { TContactAttributeKeyInput, TGetContactAttributeKeysFilter, } from "@/modules/api/v2/management/contact-attribute-keys/types/contact-attribute-keys"; -import { ContactAttributeKey } from "@prisma/client"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; +import { ContactAttributeKey, Prisma } from "@prisma/client"; import { describe, expect, test, vi } from "vitest"; import { prisma } from "@formbricks/database"; import { PrismaErrorType } from "@formbricks/database/types/error"; @@ -106,7 +105,7 @@ describe("createContactAttributeKey", () => { }); test("returns conflict error when key already exists", async () => { - const errToThrow = new PrismaClientKnownRequestError("Mock error message", { + const errToThrow = new Prisma.PrismaClientKnownRequestError("Mock error message", { code: PrismaErrorType.UniqueConstraintViolation, clientVersion: "0.0.1", }); @@ -129,7 +128,7 @@ describe("createContactAttributeKey", () => { }); test("returns not found error when related record does not exist", async () => { - const errToThrow = new PrismaClientKnownRequestError("Mock error message", { + const errToThrow = new Prisma.PrismaClientKnownRequestError("Mock error message", { code: PrismaErrorType.RelatedRecordDoesNotExist, clientVersion: "0.0.1", }); diff --git a/apps/web/modules/api/v2/management/responses/[responseId]/lib/display.ts b/apps/web/modules/api/v2/management/responses/[responseId]/lib/display.ts index 12db4aa20d..3b3fd92a5a 100644 --- a/apps/web/modules/api/v2/management/responses/[responseId]/lib/display.ts +++ b/apps/web/modules/api/v2/management/responses/[responseId]/lib/display.ts @@ -1,5 +1,5 @@ import { ApiErrorResponseV2 } from "@/modules/api/v2/types/api-error"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; +import { Prisma } from "@prisma/client"; import { prisma } from "@formbricks/database"; import { PrismaErrorType } from "@formbricks/database/types/error"; import { Result, err, ok } from "@formbricks/types/error-handlers"; @@ -19,7 +19,7 @@ export const deleteDisplay = async (displayId: string): Promise { test("return a not_found error when the display is not found", async () => { vi.mocked(prisma.display.delete).mockRejectedValue( - new PrismaClientKnownRequestError("Display not found", { + new Prisma.PrismaClientKnownRequestError("Display not found", { code: PrismaErrorType.RelatedRecordDoesNotExist, clientVersion: "1.0.0", meta: { diff --git a/apps/web/modules/api/v2/management/responses/[responseId]/lib/tests/response.test.ts b/apps/web/modules/api/v2/management/responses/[responseId]/lib/tests/response.test.ts index 63c168964c..c22b0fe7f9 100644 --- a/apps/web/modules/api/v2/management/responses/[responseId]/lib/tests/response.test.ts +++ b/apps/web/modules/api/v2/management/responses/[responseId]/lib/tests/response.test.ts @@ -1,5 +1,5 @@ import { response, responseId, responseInput, survey } from "./__mocks__/response.mock"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; +import { Prisma } from "@prisma/client"; import { beforeEach, describe, expect, test, vi } from "vitest"; import { prisma } from "@formbricks/database"; import { PrismaErrorType } from "@formbricks/database/types/error"; @@ -154,7 +154,7 @@ describe("Response Lib", () => { test("handle prisma client error code P2025", async () => { vi.mocked(prisma.response.delete).mockRejectedValue( - new PrismaClientKnownRequestError("Response not found", { + new Prisma.PrismaClientKnownRequestError("Response not found", { code: PrismaErrorType.RelatedRecordDoesNotExist, clientVersion: "1.0.0", meta: { @@ -208,7 +208,7 @@ describe("Response Lib", () => { test("return a not_found error when the response is not found", async () => { vi.mocked(prisma.response.update).mockRejectedValue( - new PrismaClientKnownRequestError("Response not found", { + new Prisma.PrismaClientKnownRequestError("Response not found", { code: PrismaErrorType.RelatedRecordDoesNotExist, clientVersion: "1.0.0", meta: { diff --git a/apps/web/modules/api/v2/management/webhooks/[webhookId]/lib/tests/mocks/webhook.mock.ts b/apps/web/modules/api/v2/management/webhooks/[webhookId]/lib/tests/mocks/webhook.mock.ts index a6b335ba5e..3a4d6a6e75 100644 --- a/apps/web/modules/api/v2/management/webhooks/[webhookId]/lib/tests/mocks/webhook.mock.ts +++ b/apps/web/modules/api/v2/management/webhooks/[webhookId]/lib/tests/mocks/webhook.mock.ts @@ -1,5 +1,4 @@ -import { WebhookSource } from "@prisma/client"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; +import { Prisma, WebhookSource } from "@prisma/client"; import { PrismaErrorType } from "@formbricks/database/types/error"; export const mockedPrismaWebhookUpdateReturn = { @@ -14,7 +13,7 @@ export const mockedPrismaWebhookUpdateReturn = { surveyIds: [], }; -export const prismaNotFoundError = new PrismaClientKnownRequestError("Record does not exist", { +export const prismaNotFoundError = new Prisma.PrismaClientKnownRequestError("Record does not exist", { code: PrismaErrorType.RecordDoesNotExist, clientVersion: "PrismaClient 4.0.0", }); diff --git a/apps/web/modules/api/v2/management/webhooks/[webhookId]/lib/webhook.ts b/apps/web/modules/api/v2/management/webhooks/[webhookId]/lib/webhook.ts index 349fdf8718..7201315c9c 100644 --- a/apps/web/modules/api/v2/management/webhooks/[webhookId]/lib/webhook.ts +++ b/apps/web/modules/api/v2/management/webhooks/[webhookId]/lib/webhook.ts @@ -1,7 +1,6 @@ import { ZWebhookUpdateSchema } from "@/modules/api/v2/management/webhooks/[webhookId]/types/webhooks"; import { ApiErrorResponseV2 } from "@/modules/api/v2/types/api-error"; -import { Webhook } from "@prisma/client"; -import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; +import { Prisma, Webhook } from "@prisma/client"; import { z } from "zod"; import { prisma } from "@formbricks/database"; import { PrismaErrorType } from "@formbricks/database/types/error"; @@ -45,7 +44,7 @@ export const updateWebhook = async ( return ok(updatedWebhook); } catch (error) { - if (error instanceof PrismaClientKnownRequestError) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { if ( error.code === PrismaErrorType.RecordDoesNotExist || error.code === PrismaErrorType.RelatedRecordDoesNotExist @@ -73,7 +72,7 @@ export const deleteWebhook = async (webhookId: string): Promise { test("returns not_found error on known prisma error", async () => { (prisma.team.delete as any).mockRejectedValueOnce( - new PrismaClientKnownRequestError("Not found", { + new Prisma.PrismaClientKnownRequestError("Not found", { code: PrismaErrorType.RecordDoesNotExist, clientVersion: "1.0.0", meta: {}, @@ -120,7 +120,7 @@ describe("Teams Lib", () => { test("returns not_found error when update fails due to missing team", async () => { (prisma.team.update as any).mockRejectedValueOnce( - new PrismaClientKnownRequestError("Not found", { + new Prisma.PrismaClientKnownRequestError("Not found", { code: PrismaErrorType.RecordDoesNotExist, clientVersion: "1.0.0", meta: {},