From 0a39f53a4bde352a88176c7e1de2856933ef67bd Mon Sep 17 00:00:00 2001 From: Morgan <33722304+ThyMinimalDev@users.noreply.github.com> Date: Thu, 16 Nov 2023 10:48:46 +0200 Subject: [PATCH] fix(stripePaymentCallback): better errors (#12223) Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: Keith Williams --- apps/web/pages/api/integrations/[...args].ts | 3 ++- .../stripepayment/api/paymentCallback.ts | 21 ++++++++++++++----- packages/lib/server/defaultResponder.ts | 7 ++++--- .../lib/server/getServerErrorFromUnknown.ts | 3 ++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/apps/web/pages/api/integrations/[...args].ts b/apps/web/pages/api/integrations/[...args].ts index ea1b68dbf5..f4e840b021 100644 --- a/apps/web/pages/api/integrations/[...args].ts +++ b/apps/web/pages/api/integrations/[...args].ts @@ -73,7 +73,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { redirectUrl = handler.redirect?.url || getInstalledAppPath(handler); res.json({ url: redirectUrl, newTab: handler.redirect?.newTab }); } - return res.status(200); + if (!res.writableEnded) return res.status(200); + return res; } catch (error) { console.error(error); if (error instanceof HttpError) { diff --git a/packages/app-store/stripepayment/api/paymentCallback.ts b/packages/app-store/stripepayment/api/paymentCallback.ts index e10df2d0bc..a9f4d0934c 100644 --- a/packages/app-store/stripepayment/api/paymentCallback.ts +++ b/packages/app-store/stripepayment/api/paymentCallback.ts @@ -3,6 +3,7 @@ import z from "zod"; import { getCustomerAndCheckoutSession } from "@calcom/app-store/stripepayment/lib/getCustomerAndCheckoutSession"; import { WEBAPP_URL } from "@calcom/lib/constants"; +import { HttpError } from "@calcom/lib/http-error"; import { defaultHandler, defaultResponder } from "@calcom/lib/server"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; @@ -22,7 +23,13 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) { const { callbackUrl, checkoutSessionId } = querySchema.parse(req.query); const { stripeCustomer, checkoutSession } = await getCustomerAndCheckoutSession(checkoutSessionId); - if (!stripeCustomer) return { message: "Stripe customer not found or deleted" }; + if (!stripeCustomer) + throw new HttpError({ + statusCode: 404, + message: "Stripe customer not found or deleted", + url: req.url, + method: req.method, + }); // first let's try to find user by metadata stripeCustomerId let user = await prisma.user.findFirst({ @@ -43,10 +50,11 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) { }); } + if (!user) + throw new HttpError({ statusCode: 404, message: "User not found", url: req.url, method: req.method }); + if (checkoutSession.payment_status === "paid" && stripeCustomer.metadata.username) { try { - if (!user) return { message: "User not found" }; - await prisma.user.update({ data: { username: stripeCustomer.metadata.username, @@ -61,10 +69,13 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) { }); } catch (error) { console.error(error); - return { + throw new HttpError({ + statusCode: 400, + url: req.url, + method: req.method, message: "We have received your payment. Your premium username could still not be reserved. Please contact support@cal.com and mention your premium username", - }; + }); } } callbackUrl.searchParams.set("paymentStatus", checkoutSession.payment_status); diff --git a/packages/lib/server/defaultResponder.ts b/packages/lib/server/defaultResponder.ts index b70f99cd04..e044354e8d 100644 --- a/packages/lib/server/defaultResponder.ts +++ b/packages/lib/server/defaultResponder.ts @@ -14,13 +14,14 @@ export function defaultResponder(f: Handle) { const result = await f(req, res); ok = true; if (result && !res.writableEnded) { - res.json(result); + return res.json(result); } } catch (err) { console.error(err); const error = getServerErrorFromUnknown(err); - res.statusCode = error.statusCode; - res.json({ message: error.message }); + return res + .status(error.statusCode) + .json({ message: error.message, url: error.url, method: error.method }); } finally { performance.mark("End"); performance.measure(`[${ok ? "OK" : "ERROR"}][$1] ${req.method} '${req.url}'`, "Start", "End"); diff --git a/packages/lib/server/getServerErrorFromUnknown.ts b/packages/lib/server/getServerErrorFromUnknown.ts index 081be54ebe..a1118be888 100644 --- a/packages/lib/server/getServerErrorFromUnknown.ts +++ b/packages/lib/server/getServerErrorFromUnknown.ts @@ -55,7 +55,8 @@ export function getServerErrorFromUnknown(cause: unknown): HttpError { const redactedCause = redactError(cause); return { ...redactedCause, - message: redactedCause.message, + name: cause.name, + message: cause.message ?? "", cause: cause.cause, url: cause.url, statusCode: cause.statusCode,