Error Handling
Learn how to handle errors effectively in your API endpoints.
Using ORPCError
The project uses ORPCError for standardized error handling. This ensures consistent error responses across your API.
Basic Usage
import { ORPCError } from "@orpc/server";
export const exampleAction = protectedProcedure
.route({
method: "POST",
path: "/example",
})
.handler(async ({ input }) => {
if (!isValid(input)) {
throw new ORPCError("BAD_REQUEST", {
message: "Invalid input data",
});
}
return { success: true };
});Error Codes
Standard HTTP Error Codes
oRPC supports standard HTTP error codes:
| Code | HTTP Status | Description | Use Case |
|---|---|---|---|
BAD_REQUEST | 400 | Invalid request | Input validation failures |
UNAUTHORIZED | 401 | Not authenticated | Missing or invalid session |
FORBIDDEN | 403 | No permission | Insufficient permissions |
NOT_FOUND | 404 | Resource not found | Resource doesn't exist |
CONFLICT | 409 | Resource conflict | Duplicate entries |
TOO_MANY_REQUESTS | 429 | Rate limit exceeded | Too many requests |
INTERNAL_SERVER_ERROR | 500 | Server error | Unexpected errors |
Common Patterns
Validation Errors
export const createUser = publicProcedure
.route({
method: "POST",
path: "/users",
})
.input(userSchema)
.handler(async ({ input }) => {
// Check if email already exists
const existing = await findUserByEmail(input.email);
if (existing) {
throw new ORPCError("CONFLICT", {
message: "Email already registered",
cause: { field: "email" },
});
}
return await createUser(input);
});Resource Not Found
export const getUser = publicProcedure
.route({
method: "GET",
path: "/users/:id",
})
.input(z.object({
id: z.string(),
}))
.handler(async ({ input }) => {
const user = await findUserById(input.id);
if (!user) {
throw new ORPCError("NOT_FOUND", {
message: `User with ID ${input.id} not found`,
});
}
return user;
});Error Messages
User-Friendly Messages
Provide clear, actionable error messages:
// Good - Clear and actionable
throw new ORPCError("BAD_REQUEST", {
message: "Password must be at least 8 characters long",
});
// Bad - Vague and unhelpful
throw new ORPCError("BAD_REQUEST", {
message: "Invalid input",
});Including Error Details
Add context to help debugging:
throw new ORPCError("CONFLICT", {
message: "Username already taken",
cause: {
field: "username",
value: input.username,
suggestion: "Try adding numbers or your name",
},
});