Always use the appropriate error classes and throwing mechanisms for consistent error handling across the codebase. Prefer BetterAuthError or APIError over generic Error classes, use throw instead of returning error responses in endpoints, and structure error codes consistently.

Key practices:

Example:

// โŒ Avoid
throw new Error("unable to set a future iat time");
return ctx.json({ error: "invalid_grant" }, { status: 400 });

// โœ… Prefer  
throw new BetterAuthError("unable to set a future iat time");
throw new APIError("BAD_REQUEST", {
  message: ERROR_CODES.INVALID_GRANT,
  code: "INVALID_GRANT"
});

This ensures proper error type inference, consistent error handling patterns, and better debugging experience across the application.