refactor: Specific error status codes (#18847)
This commit is contained in:
@@ -93,10 +93,7 @@ test.describe("free user", () => {
|
||||
await page.goto(bookingUrl);
|
||||
|
||||
// book same time spot again
|
||||
await bookTimeSlot(page, {
|
||||
/** FIXME: this should be a 409 conflict */
|
||||
expectedStatusCode: 500,
|
||||
});
|
||||
await bookTimeSlot(page, { expectedStatusCode: 409 });
|
||||
|
||||
await page.locator("[data-testid=booking-fail]").waitFor({ state: "visible" });
|
||||
});
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { ErrorCode } from "@calcom/lib/errorCodes";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
import { defaultResponder } from "./defaultResponder";
|
||||
|
||||
@@ -19,4 +23,18 @@ describe("defaultResponder", () => {
|
||||
await defaultResponder(f)(req, res);
|
||||
expect(res.json).not.toHaveBeenCalled();
|
||||
});
|
||||
it("should respond with status code 409 for NoAvailableUsersFound", async () => {
|
||||
const f = vi.fn().mockRejectedValue(new Error(ErrorCode.NoAvailableUsersFound));
|
||||
const req = {} as NextApiRequest;
|
||||
const res = { status: vi.fn().mockReturnThis(), json: vi.fn() } as unknown as NextApiResponse;
|
||||
await defaultResponder(f)(req, res);
|
||||
expect(res.status).toHaveBeenCalledWith(409);
|
||||
});
|
||||
it("Rate limit should respond with a 429 status code", async () => {
|
||||
const f = vi.fn().mockRejectedValue(new TRPCError({ code: "TOO_MANY_REQUESTS" }));
|
||||
const req = {} as NextApiRequest;
|
||||
const res = { status: vi.fn().mockReturnThis(), json: vi.fn() } as unknown as NextApiResponse;
|
||||
await defaultResponder(f)(req, res);
|
||||
expect(res.status).toHaveBeenCalledWith(429);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,9 +27,9 @@ export function defaultResponder<T>(
|
||||
const error = getServerErrorFromUnknown(err);
|
||||
// we don't want to report Bad Request errors to Sentry / console
|
||||
if (!(error.statusCode >= 400 && error.statusCode < 500)) {
|
||||
console.error(err);
|
||||
console.error(error);
|
||||
const captureException = (await import("@sentry/nextjs")).captureException;
|
||||
captureException(err);
|
||||
captureException(error);
|
||||
}
|
||||
return res
|
||||
.status(error.statusCode)
|
||||
|
||||
@@ -3,6 +3,8 @@ import Stripe from "stripe";
|
||||
import type { ZodIssue } from "zod";
|
||||
import { ZodError } from "zod";
|
||||
|
||||
import { ErrorCode } from "@calcom/lib/errorCodes";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { getHTTPStatusCodeFromError } from "@trpc/server/http";
|
||||
|
||||
@@ -70,7 +72,8 @@ export function getServerErrorFromUnknown(cause: unknown): HttpError {
|
||||
};
|
||||
}
|
||||
if (cause instanceof Error) {
|
||||
return getHttpError({ statusCode: 500, cause });
|
||||
const statusCode = getStatusCode(cause);
|
||||
return getHttpError({ statusCode, cause });
|
||||
}
|
||||
if (typeof cause === "string") {
|
||||
// @ts-expect-error https://github.com/tc39/proposal-error-cause
|
||||
@@ -83,6 +86,34 @@ export function getServerErrorFromUnknown(cause: unknown): HttpError {
|
||||
});
|
||||
}
|
||||
|
||||
function getStatusCode(cause: Error): number {
|
||||
switch (cause.message) {
|
||||
case ErrorCode.RequestBodyWithouEnd:
|
||||
case ErrorCode.MissingPaymentCredential:
|
||||
case ErrorCode.MissingPaymentAppId:
|
||||
case ErrorCode.AvailabilityNotFoundInSchedule:
|
||||
return 400;
|
||||
case ErrorCode.CancelledBookingsCannotBeRescheduled:
|
||||
return 403;
|
||||
case ErrorCode.NoAvailableUsersFound:
|
||||
case ErrorCode.HostsUnavailableForBooking:
|
||||
case ErrorCode.PaymentCreationFailure:
|
||||
case ErrorCode.ChargeCardFailure:
|
||||
case ErrorCode.AlreadySignedUpForBooking:
|
||||
case ErrorCode.BookingSeatsFull:
|
||||
case ErrorCode.NotEnoughAvailableSeats:
|
||||
return 409;
|
||||
case ErrorCode.EventTypeNotFound:
|
||||
case ErrorCode.BookingNotFound:
|
||||
return 404;
|
||||
case ErrorCode.UnableToSubscribeToThePlatform:
|
||||
case ErrorCode.UpdatingOauthClientError:
|
||||
case ErrorCode.CreatingOauthClientError:
|
||||
default:
|
||||
return 500;
|
||||
}
|
||||
}
|
||||
|
||||
function getHttpError<T extends Error>({ statusCode, cause }: { statusCode: number; cause: T }) {
|
||||
const redacted = redactError(cause);
|
||||
return new HttpError({ statusCode, message: redacted.message, cause: redacted });
|
||||
|
||||
Reference in New Issue
Block a user