docs: add ErrorWithCode vs TRPCError guidelines and packages/features import restrictions (#25751)

* docs: add ErrorWithCode vs TRPCError guidelines and packages/features import restrictions

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: correct ErrorWithCode syntax with proper imports and Factory pattern

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: update AGENTS.md with ErrorWithCode guidance for non-tRPC files

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: reduce duplication by linking to knowledge-base.md for error handling details

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Eunjae Lee
2025-12-10 13:39:27 +00:00
committed by GitHub
co-authored by Devin AI
parent e6bfdd9ebb
commit 41b71d845c
2 changed files with 27 additions and 6 deletions
+4 -5
View File
@@ -7,7 +7,7 @@ You are a senior Cal.com engineer working in a Yarn/Turbo monorepo. You prioriti
- Use `select` instead of `include` in Prisma queries for performance and security
- Use `import type { X }` for TypeScript type imports
- Use early returns to reduce nesting: `if (!booking) return null;`
- Use TRPCError with proper error codes for API errors
- Use `ErrorWithCode` for errors in non-tRPC files (services, repositories, utilities); use `TRPCError` only in tRPC routers
- Use conventional commits: `feat:`, `fix:`, `refactor:`
- Create PRs in draft mode by default
- Run `yarn type-check:ci --force` before concluding CI failures are unrelated to your changes
@@ -131,15 +131,14 @@ packages/lib/ # Shared utilities
```typescript
// Good - Descriptive error with context
throw new TRPCError({
code: "BAD_REQUEST",
message: `Unable to create booking: User ${userId} has no available time slots for ${date}`,
});
throw new Error(`Unable to create booking: User ${userId} has no available time slots for ${date}`);
// Bad - Generic error
throw new Error("Booking failed");
```
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).
### Good Prisma query
```typescript
+23 -1
View File
@@ -225,16 +225,38 @@ throw new Error("Booking failed");
### Error Types
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.
```typescript
// ✅ Good - Use proper error classes
// ✅ Good - Use ErrorWithCode in non-tRPC files (services, repositories, utilities)
import { ErrorCode } from "@calcom/lib/errorCodes";
import { ErrorWithCode } from "@calcom/lib/errors";
// Option 1: Using constructor with ErrorCode enum
throw new ErrorWithCode(ErrorCode.BookingNotFound, "Booking not found");
// Option 2: Using the Factory pattern for common HTTP errors
throw ErrorWithCode.Factory.Forbidden("You don't have permission to view this");
throw ErrorWithCode.Factory.NotFound("Resource not found");
throw ErrorWithCode.Factory.BadRequest("Invalid input");
// ✅ Good - Use TRPCError only in tRPC routers/procedures
import { TRPCError } from "@trpc/server";
throw new TRPCError({
code: "BAD_REQUEST",
message: "Invalid booking time slot",
});
// ❌ Bad - Using TRPCError in non-tRPC files
import { TRPCError } from "@trpc/server";
// Don't use TRPCError in services, repositories, or utility files
```
### packages/features Import Restrictions
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.
## Basic Performance Guidelines
- Aim for O(n) or O(n log n) complexity, avoid O(n²)