diff --git a/packages/lib/services/actions.ts b/packages/lib/services/actions.ts index ffa8b2475a..08038ba032 100644 --- a/packages/lib/services/actions.ts +++ b/packages/lib/services/actions.ts @@ -2,7 +2,7 @@ import "server-only"; import z from "zod"; import { prisma } from "@formbricks/database"; -import { DatabaseError } from "@formbricks/types/v1/errors"; +import { DatabaseError, ResourceNotFoundError } from "@formbricks/types/v1/errors"; import { TAction } from "@formbricks/types/v1/actions"; import { ZId } from "@formbricks/types/v1/environment"; import { Prisma } from "@prisma/client"; @@ -65,7 +65,7 @@ export const createAction = async (data: TJsActionInput) => { const session = await getSessionCached(sessionId); if (!session) { - throw new Error("Session not found"); + throw new ResourceNotFoundError("Session", sessionId); } const actionClass = await getActionClassCached(name, environmentId); diff --git a/packages/lib/services/activity.tsx b/packages/lib/services/activity.tsx index 55ba044ffd..c9215812f6 100644 --- a/packages/lib/services/activity.tsx +++ b/packages/lib/services/activity.tsx @@ -5,6 +5,7 @@ import { TActivityFeedItem } from "@formbricks/types/v1/activity"; import { validateInputs } from "../utils/validate"; import { ZId } from "@formbricks/types/v1/environment"; import { cache } from "react"; +import { ResourceNotFoundError } from "@formbricks/types/v1/errors"; export const getActivityTimeline = cache(async (personId: string): Promise => { validateInputs([personId, ZId]); @@ -34,8 +35,9 @@ export const getActivityTimeline = cache(async (personId: string): Promise => { validateInputs([displayId, ZId]); try { - if (!displayId) throw new Error("Display ID is required"); + if (!displayId) { + throw new ResourceNotFoundError("Display", displayId); + } const displayPrisma = await prisma.display.update({ where: { diff --git a/packages/lib/services/googleSheet.ts b/packages/lib/services/googleSheet.ts index 1f8900a889..c7daae2b2b 100644 --- a/packages/lib/services/googleSheet.ts +++ b/packages/lib/services/googleSheet.ts @@ -2,7 +2,7 @@ import "server-only"; import { prisma } from "@formbricks/database"; import { Prisma } from "@prisma/client"; -import { DatabaseError } from "@formbricks/types/v1/errors"; +import { DatabaseError, UnknownError } from "@formbricks/types/v1/errors"; import { cache } from "react"; import { TGoogleCredential, @@ -89,8 +89,7 @@ export async function writeData(credentials: TGoogleCredential, spreadsheetId: s }, (err: Error) => { if (err) { - throw new Error(`Error while appending data: ${err.message}`); - } else { + throw new UnknownError(`Error while appending data: ${err.message}`); } } ); @@ -104,8 +103,7 @@ export async function writeData(credentials: TGoogleCredential, spreadsheetId: s }, (err: Error) => { if (err) { - throw new Error(`Error while appending data: ${err.message}`); - } else { + throw new UnknownError(`Error while appending data: ${err.message}`); } } ); diff --git a/packages/lib/services/membership.ts b/packages/lib/services/membership.ts index 16f0123aaa..470cc72280 100644 --- a/packages/lib/services/membership.ts +++ b/packages/lib/services/membership.ts @@ -1,7 +1,7 @@ import "server-only"; import { prisma } from "@formbricks/database"; -import { ResourceNotFoundError } from "@formbricks/types/v1/errors"; +import { ResourceNotFoundError, DatabaseError, UnknownError } from "@formbricks/types/v1/errors"; import { TMember, TMembership, TMembershipUpdateInput } from "@formbricks/types/v1/memberships"; import { Prisma } from "@prisma/client"; import { cache } from "react"; @@ -102,9 +102,9 @@ export const updateMembership = async ( } catch (error) { if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2016") { throw new ResourceNotFoundError("Membership", `userId: ${userId}, teamId: ${teamId}`); - } else { - throw error; // Re-throw any other errors } + + throw error; } }; @@ -148,6 +148,11 @@ export const transferOwnership = async (currentOwnerId: string, newOwnerId: stri }), ]); } catch (error) { - throw new Error("Something went wrong"); + if (error instanceof Prisma.PrismaClientKnownRequestError) { + throw new DatabaseError("Database operation failed"); + } + + const message = error instanceof Error ? error.message : ""; + throw new UnknownError(`Error while transfering ownership: ${message}`); } }; diff --git a/packages/lib/services/person.ts b/packages/lib/services/person.ts index 21a89535b9..ae5bb4c0b2 100644 --- a/packages/lib/services/person.ts +++ b/packages/lib/services/person.ts @@ -2,7 +2,7 @@ import "server-only"; import { prisma } from "@formbricks/database"; import { ZId } from "@formbricks/types/v1/environment"; -import { DatabaseError } from "@formbricks/types/v1/errors"; +import { DatabaseError, ResourceNotFoundError } from "@formbricks/types/v1/errors"; import { TPerson, TPersonUpdateInput } from "@formbricks/types/v1/people"; import { Prisma } from "@prisma/client"; import { revalidateTag, unstable_cache } from "next/cache"; @@ -250,7 +250,7 @@ export const getOrCreatePersonByUserId = async (userId: string, environmentId: s const userIdAttributeClass = await getAttributeClassByName(environmentId, "userId"); if (!userIdAttributeClass) { - throw new Error("Attribute class not found for the given environmentId"); + throw new ResourceNotFoundError("Attribute class not found for the given environment", environmentId); } const personPrisma = await prisma.person.create({ diff --git a/packages/lib/services/team.ts b/packages/lib/services/team.ts index 63883dca4b..c7371ecc83 100644 --- a/packages/lib/services/team.ts +++ b/packages/lib/services/team.ts @@ -2,7 +2,7 @@ import "server-only"; import { prisma } from "@formbricks/database"; import { ZId } from "@formbricks/types/v1/environment"; -import { DatabaseError, ResourceNotFoundError } from "@formbricks/types/v1/errors"; +import { DatabaseError, ResourceNotFoundError, ValidationError } from "@formbricks/types/v1/errors"; import { TTeam, TTeamUpdateInput } from "@formbricks/types/v1/teams"; import { createId } from "@paralleldrive/cuid2"; import { Prisma } from "@prisma/client"; @@ -245,7 +245,7 @@ export const createDemoProduct = async (teamId: string) => { // check if updatedEnvironment exists and it has attributeClasses if (!updatedEnvironment || !updatedEnvironment.attributeClasses) { - throw new Error("Attribute classes could not be created"); + throw new ValidationError("Attribute classes could not be created"); } const attributeClasses = updatedEnvironment.attributeClasses; @@ -332,8 +332,12 @@ export const createDemoProduct = async (teamId: string) => { })), }), ]); - } catch (err: any) { - throw new Error(err); + } catch (error: any) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + throw new DatabaseError("Database operation failed"); + } + + throw error; } // Create a function that creates a survey diff --git a/packages/types/v1/errors.ts b/packages/types/v1/errors.ts index e86054c477..1d2e8ee850 100644 --- a/packages/types/v1/errors.ts +++ b/packages/types/v1/errors.ts @@ -22,6 +22,14 @@ class ValidationError extends Error { } } +class UnknownError extends Error { + statusCode = 500; + constructor(message: string) { + super(message); + this.name = "DatabaseError"; + } +} + class DatabaseError extends Error { statusCode = 500; constructor(message: string) { @@ -83,6 +91,7 @@ export { ValidationError, DatabaseError, UniqueConstraintError, + UnknownError, ForeignKeyConstraintError, OperationNotAllowedError, AuthenticationError,