From 1334e7a3f9c02f08becf0cf7afcf0af2749be02e Mon Sep 17 00:00:00 2001 From: Matthias Nannt Date: Wed, 14 Jun 2023 17:55:04 +0200 Subject: [PATCH] fix bug creating responses, improve error handling in survey service --- .../v1/client/responses/[responseId]/route.ts | 8 +- apps/web/app/api/v1/client/responses/route.ts | 6 +- packages/lib/services/survey.ts | 75 ++++++++++--------- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/apps/web/app/api/v1/client/responses/[responseId]/route.ts b/apps/web/app/api/v1/client/responses/[responseId]/route.ts index ed4e10c904..daad1011c2 100644 --- a/apps/web/app/api/v1/client/responses/[responseId]/route.ts +++ b/apps/web/app/api/v1/client/responses/[responseId]/route.ts @@ -31,7 +31,7 @@ export async function PUT( // update response let response; try { - response = await updateResponse(responseId, responseUpdate); + response = await updateResponse(responseId, inputValidation.data); } catch (error) { if (error instanceof ResourceNotFoundError) { return responses.notFoundResponse("Response", responseId, true); @@ -62,7 +62,11 @@ export async function PUT( sendToPipeline("responseUpdated", { environmentId: survey.environmentId, surveyId: survey.id, - data: response, + // only send the updated fields + data: { + ...response, + data: inputValidation.data.data, + }, }); if (response.finished) { diff --git a/apps/web/app/api/v1/client/responses/route.ts b/apps/web/app/api/v1/client/responses/route.ts index eff0065859..1eb52cc3d2 100644 --- a/apps/web/app/api/v1/client/responses/route.ts +++ b/apps/web/app/api/v1/client/responses/route.ts @@ -33,8 +33,7 @@ export async function POST(request: Request): Promise { } catch (error) { if (error instanceof InvalidInputError) { return responses.badRequestResponse(error.message); - } - if (error instanceof DatabaseError) { + } else { return responses.internalServerErrorResponse(error.message); } } @@ -78,8 +77,7 @@ export async function POST(request: Request): Promise { } catch (error) { if (error instanceof InvalidInputError) { return responses.badRequestResponse(error.message); - } - if (error instanceof DatabaseError) { + } else { return responses.internalServerErrorResponse(error.message); } } diff --git a/packages/lib/services/survey.ts b/packages/lib/services/survey.ts index b7f5d12bb1..a78a76b596 100644 --- a/packages/lib/services/survey.ts +++ b/packages/lib/services/survey.ts @@ -1,11 +1,13 @@ import { prisma } from "@formbricks/database"; +import { ValidationError } from "@formbricks/errors"; import { DatabaseError, ResourceNotFoundError } from "@formbricks/errors"; import { TSurvey, ZSurvey } from "@formbricks/types/v1/surveys"; import { Prisma } from "@prisma/client"; export const getSurvey = async (surveyId: string): Promise => { + let surveyPrisma; try { - const surveyPrisma = await prisma.survey.findUnique({ + surveyPrisma = await prisma.survey.findUnique({ where: { id: surveyId, }, @@ -33,41 +35,6 @@ export const getSurvey = async (surveyId: string): Promise => { }, }, }); - - if (!surveyPrisma) { - throw new ResourceNotFoundError("Survey", surveyId); - } - - const numDisplays = await prisma.display.count({ - where: { - surveyId, - }, - }); - - const numDisplaysResponded = await prisma.display.count({ - where: { - surveyId, - status: "responded", - }, - }); - - // responseRate, rounded to 2 decimal places - const responseRate = Math.round((numDisplaysResponded / numDisplays) * 100) / 100; - - const transformedSurvey = { - ...surveyPrisma, - createdAt: surveyPrisma.createdAt.toISOString(), - updatedAt: surveyPrisma.updatedAt.toISOString(), - triggers: surveyPrisma.triggers.map((trigger) => trigger.eventClass), - analytics: { - numDisplays, - responseRate, - }, - }; - - const survey = ZSurvey.parse(transformedSurvey); - - return survey; } catch (error) { if (error instanceof Prisma.PrismaClientKnownRequestError) { throw new DatabaseError("Database operation failed"); @@ -75,4 +42,40 @@ export const getSurvey = async (surveyId: string): Promise => { throw error; } + + if (!surveyPrisma) { + throw new ResourceNotFoundError("Survey", surveyId); + } + + const numDisplays = await prisma.display.count({ + where: { + surveyId, + }, + }); + + const numDisplaysResponded = await prisma.display.count({ + where: { + surveyId, + status: "responded", + }, + }); + + // responseRate, rounded to 2 decimal places + const responseRate = Math.round((numDisplaysResponded / numDisplays) * 100) / 100; + + const transformedSurvey = { + ...surveyPrisma, + triggers: surveyPrisma.triggers.map((trigger) => trigger.eventClass), + analytics: { + numDisplays, + responseRate, + }, + }; + + try { + const survey = ZSurvey.parse(transformedSurvey); + return survey; + } catch (error) { + throw new ValidationError("Data validation of survey failed"); + } };