Skip to content

Commit 41b71d8

Browse files
docs: add ErrorWithCode vs TRPCError guidelines and packages/features import restrictions (calcom#25751)
* docs: add ErrorWithCode vs TRPCError guidelines and packages/features import restrictions Co-Authored-By: [email protected] <[email protected]> * fix: correct ErrorWithCode syntax with proper imports and Factory pattern Co-Authored-By: [email protected] <[email protected]> * docs: update AGENTS.md with ErrorWithCode guidance for non-tRPC files Co-Authored-By: [email protected] <[email protected]> * docs: reduce duplication by linking to knowledge-base.md for error handling details Co-Authored-By: [email protected] <[email protected]> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent e6bfdd9 commit 41b71d8

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

AGENTS.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ You are a senior Cal.com engineer working in a Yarn/Turbo monorepo. You prioriti
77
- Use `select` instead of `include` in Prisma queries for performance and security
88
- Use `import type { X }` for TypeScript type imports
99
- Use early returns to reduce nesting: `if (!booking) return null;`
10-
- Use TRPCError with proper error codes for API errors
10+
- Use `ErrorWithCode` for errors in non-tRPC files (services, repositories, utilities); use `TRPCError` only in tRPC routers
1111
- Use conventional commits: `feat:`, `fix:`, `refactor:`
1212
- Create PRs in draft mode by default
1313
- Run `yarn type-check:ci --force` before concluding CI failures are unrelated to your changes
@@ -131,15 +131,14 @@ packages/lib/ # Shared utilities
131131

132132
```typescript
133133
// Good - Descriptive error with context
134-
throw new TRPCError({
135-
code: "BAD_REQUEST",
136-
message: `Unable to create booking: User ${userId} has no available time slots for ${date}`,
137-
});
134+
throw new Error(`Unable to create booking: User ${userId} has no available time slots for ${date}`);
138135

139136
// Bad - Generic error
140137
throw new Error("Booking failed");
141138
```
142139

140+
For which error class to use (`ErrorWithCode` vs `TRPCError`) and concrete examples, see [Error Types in knowledge-base.md](agents/knowledge-base.md#error-types).
141+
143142
### Good Prisma query
144143

145144
```typescript

agents/knowledge-base.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,38 @@ throw new Error("Booking failed");
225225

226226
### Error Types
227227

228+
Use `ErrorWithCode` for files that are not directly coupled to tRPC. The tRPC package has a middleware called `errorConversionMiddleware` that automatically converts `ErrorWithCode` instances into `TRPCError` instances.
229+
228230
```typescript
229-
// ✅ Good - Use proper error classes
231+
// ✅ Good - Use ErrorWithCode in non-tRPC files (services, repositories, utilities)
232+
import { ErrorCode } from "@calcom/lib/errorCodes";
233+
import { ErrorWithCode } from "@calcom/lib/errors";
234+
235+
// Option 1: Using constructor with ErrorCode enum
236+
throw new ErrorWithCode(ErrorCode.BookingNotFound, "Booking not found");
237+
238+
// Option 2: Using the Factory pattern for common HTTP errors
239+
throw ErrorWithCode.Factory.Forbidden("You don't have permission to view this");
240+
throw ErrorWithCode.Factory.NotFound("Resource not found");
241+
throw ErrorWithCode.Factory.BadRequest("Invalid input");
242+
243+
// ✅ Good - Use TRPCError only in tRPC routers/procedures
230244
import { TRPCError } from "@trpc/server";
231245

232246
throw new TRPCError({
233247
code: "BAD_REQUEST",
234248
message: "Invalid booking time slot",
235249
});
250+
251+
// ❌ Bad - Using TRPCError in non-tRPC files
252+
import { TRPCError } from "@trpc/server";
253+
// Don't use TRPCError in services, repositories, or utility files
236254
```
237255

256+
### packages/features Import Restrictions
257+
258+
Files in `packages/features/**` should NOT import from `trpc`. This keeps the features package decoupled from the tRPC layer, making the code more reusable and testable. Use `ErrorWithCode` for error handling in these files, and let the tRPC middleware handle the conversion.
259+
238260
## Basic Performance Guidelines
239261

240262
- Aim for O(n) or O(n log n) complexity, avoid O(n²)

0 commit comments

Comments
 (0)