Skip to content

Commit ddcac4b

Browse files
fix: make linting required for CI (calcom#27091)
* fix: make linting required for CI - Remove continue-on-error from lint workflow so CI fails on lint errors - Fix 2 lint errors: avoid importing from @trpc/server in lib package - Add trpcErrorUtils.ts to handle TRPC errors without circular dependencies - Update lint-staged to show warnings but not block commits Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com> * fix: add message field validation to isTRPCErrorLike type guard Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent f17933b commit ddcac4b

5 files changed

Lines changed: 64 additions & 16 deletions

File tree

.github/workflows/lint.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@ jobs:
1616
- uses: ./.github/actions/yarn-install
1717
- name: Run Lint
1818
run: yarn lint
19-
continue-on-error: true

lint-staged.config.mjs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
const skipWarnings = ["1", "true", "yes", "on"].includes(
2-
(process.env.SKIP_WARNINGS ?? "").toLowerCase()
3-
);
4-
51
export default {
62
"(apps|packages|companion)/**/*.{js,ts,jsx,tsx}": (files) =>
7-
skipWarnings
8-
? `biome lint --config-path=biome-staged.json ${files.join(" ")}`
9-
: `biome lint --config-path=biome-staged.json --error-on-warnings ${files.join(" ")}`,
3+
`biome lint --config-path=biome-staged.json ${files.join(" ")}`,
104
"packages/prisma/schema.prisma": ["prisma format"],
115
};

packages/lib/server/defaultResponder.test.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,19 @@ import { describe, expect, it, vi } from "vitest";
33

44
import { ErrorCode } from "@calcom/lib/errorCodes";
55

6-
import { TRPCError } from "@trpc/server";
7-
86
import { defaultResponder } from "./defaultResponder";
97

8+
/**
9+
* Creates a mock TRPC-like error for testing purposes.
10+
* This avoids importing from @trpc/server in the lib package.
11+
*/
12+
function createMockTRPCError(code: string): Error {
13+
const error = new Error(`TRPC Error: ${code}`);
14+
error.name = "TRPCError";
15+
(error as Error & { code: string }).code = code;
16+
return error;
17+
}
18+
1019
describe("defaultResponder", () => {
1120
it("should call res.json when response is still writable and result is not null", async () => {
1221
const f = vi.fn().mockResolvedValue({});
@@ -43,7 +52,7 @@ describe("defaultResponder", () => {
4352
expect(res.status).toHaveBeenCalledWith(409);
4453
});
4554
it("Rate limit should respond with a 429 status code", async () => {
46-
const f = vi.fn().mockRejectedValue(new TRPCError({ code: "TOO_MANY_REQUESTS" }));
55+
const f = vi.fn().mockRejectedValue(createMockTRPCError("TOO_MANY_REQUESTS"));
4756
const req = {} as NextApiRequest;
4857
const res = {
4958
status: vi.fn().mockReturnThis(),

packages/lib/server/defaultResponder.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import type { NextApiRequest, NextApiResponse } from "next";
22

3-
import { TRPCError } from "@trpc/server";
4-
import { getHTTPStatusCodeFromError } from "@trpc/server/http";
5-
63
import { type TraceContext } from "@calcom/lib/tracing";
74
import { TracedError } from "@calcom/lib/tracing/error";
85
import { distributedTracing } from "@calcom/lib/tracing/factory";
@@ -11,6 +8,7 @@ import { HttpError } from "../http-error";
118
import { safeStringify } from "../safeStringify";
129
import { getServerErrorFromUnknown } from "./getServerErrorFromUnknown";
1310
import { performance } from "./perfObserver";
11+
import { getHTTPStatusCodeFromTRPCErrorLike, isTRPCErrorLike } from "./trpcErrorUtils";
1412

1513
export interface TracedRequest extends NextApiRequest {
1614
traceContext: TraceContext;
@@ -58,8 +56,8 @@ export function defaultResponder<T>(
5856
tracingLogger.error(`${operation} request failed`, safeStringify(err));
5957
const tracedError = TracedError.createFromError(err, traceContext);
6058
let error: HttpError;
61-
if (err instanceof TRPCError) {
62-
const statusCode = getHTTPStatusCodeFromError(err);
59+
if (isTRPCErrorLike(err)) {
60+
const statusCode = getHTTPStatusCodeFromTRPCErrorLike(err);
6361
error = new HttpError({ statusCode, message: err.message });
6462
} else {
6563
error = getServerErrorFromUnknown(tracedError);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Utility functions for handling TRPC-like errors without importing from @trpc/server.
3+
* This avoids circular dependencies in the lib package.
4+
*/
5+
6+
const TRPC_ERROR_CODES_TO_HTTP: Record<string, number> = {
7+
PARSE_ERROR: 400,
8+
BAD_REQUEST: 400,
9+
UNAUTHORIZED: 401,
10+
NOT_FOUND: 404,
11+
FORBIDDEN: 403,
12+
METHOD_NOT_SUPPORTED: 405,
13+
TIMEOUT: 408,
14+
CONFLICT: 409,
15+
PRECONDITION_FAILED: 412,
16+
PAYLOAD_TOO_LARGE: 413,
17+
UNPROCESSABLE_CONTENT: 422,
18+
TOO_MANY_REQUESTS: 429,
19+
CLIENT_CLOSED_REQUEST: 499,
20+
INTERNAL_SERVER_ERROR: 500,
21+
NOT_IMPLEMENTED: 501,
22+
BAD_GATEWAY: 502,
23+
SERVICE_UNAVAILABLE: 503,
24+
GATEWAY_TIMEOUT: 504,
25+
};
26+
27+
interface TRPCErrorLike {
28+
name: string;
29+
code: string;
30+
message: string;
31+
}
32+
33+
export function isTRPCErrorLike(err: unknown): err is TRPCErrorLike {
34+
return (
35+
err !== null &&
36+
typeof err === "object" &&
37+
"name" in err &&
38+
err.name === "TRPCError" &&
39+
"code" in err &&
40+
typeof (err as TRPCErrorLike).code === "string" &&
41+
"message" in err &&
42+
typeof (err as TRPCErrorLike).message === "string"
43+
);
44+
}
45+
46+
export function getHTTPStatusCodeFromTRPCErrorLike(err: TRPCErrorLike): number {
47+
return TRPC_ERROR_CODES_TO_HTTP[err.code] ?? 500;
48+
}

0 commit comments

Comments
 (0)