How to Handle Errors in Kaneo: Backend and Frontend Error Management Patterns
Kaneo uses a layered error-handling architecture where the backend throws HTTPException with specific HTTP status codes, and the frontend parses these into five categorized ApiError types with built-in troubleshooting guidance.
Error handling in Kaneo follows a strict separation of concerns between the API layer and the web client. The open-source project management platform uses HTTPException from Hono to signal failures from the backend, while the frontend normalizes these into a consistent ApiError shape. This guide examines the implementation details in the usekaneo/kaneo repository, showing you how to leverage the built-in error classification system and troubleshooting helpers.
Backend Error Handling with HTTPException
The Kaneo API layer uses HTTPException from hono/http-exception to communicate failure states to clients. This approach ensures that every error carries a meaningful HTTP status code and optional message, allowing the frontend to react appropriately without leaking internal stack traces.
Throwing HTTPException in Task Controllers
In apps/api/src/task/controllers/update-task.ts, controllers validate inputs and enforce business rules before throwing specific exceptions:
import { HTTPException } from 'hono/http-exception';
import { getTaskById } from '@/services/task';
export async function updateTask(c) {
const { id } = c.req.valid('param');
const data = await c.req.json();
const task = await getTaskById(id);
if (!task) {
throw new HTTPException(404, { message: 'Task not found' });
}
if (!c.get('userId')) {
throw new HTTPException(401, { message: 'Unauthorized' });
}
// …perform update…
return c.json({ success: true });
}
Authentication and Validation Error Patterns
The backend centralizes common error scenarios in utility files. The apps/api/src/utils/authenticate-api-request.ts middleware validates API keys and converts auth failures into HTTPException with 401 or 403 status codes. Similarly, apps/api/src/utils/validate-dates.ts throws 400 Bad Request responses when date validation fails, ensuring consistent error signaling across the API surface.
Frontend Error Classification and Parsing
The web application converts raw fetch errors into a uniform ApiError type using the centralized parser in apps/web/src/lib/error-handler.ts. This module classifies every error into one of five categories: network, CORS, auth, server, or unknown.
Using parseApiError to Categorize Failures
The parseApiError(error) function inspects the error object to determine its type. It distinguishes between network failures (offline/DNS issues), CORS misconfigurations, authentication problems (401/403), server errors (5xx), and unexpected exceptions. Each classification includes the original error for debugging while presenting a sanitized message to users.
Troubleshooting Helper Functions
For CORS and network errors, Kaneo provides ready-made guidance through getCorsTroubleshootingSteps() and getNetworkTroubleshootingSteps(). These functions return arrays of actionable steps that UI components can display directly to users, reducing friction when connectivity issues occur.
Implementing Error Handling in React Components
Kaneo integrates error handling with TanStack Query and toast notifications. The pattern involves wrapping fetch calls with parseApiError and displaying categorized messages through the toast utility in apps/web/src/lib/toast.ts.
// A fetcher that uses the error-handler
import { parseApiError, getCorsTroubleshootingSteps, getNetworkTroubleshootingSteps } from '@/lib/error-handler';
import { toast } from '@/lib/toast';
export async function fetchTasks(projectId: string) {
try {
const resp = await fetch(`${import.meta.env.VITE_API_URL}/projects/${projectId}/tasks`);
if (!resp.ok) {
// Wrap non‑2xx responses in an Error so parseApiError can categorize them
throw new Error(`HTTP ${resp.status}`);
}
return await resp.json();
} catch (rawErr) {
const err = parseApiError(rawErr);
toast.error(err.message, {
// Show troubleshooting steps for CORS or network problems
details: err.type === 'cors' ? getCorsTroubleshootingSteps()
: err.type === 'network' ? getNetworkTroubleshootingSteps()
: [],
});
// Re‑throw if you need higher‑level handling
throw err;
}
}
// Using TanStack Query with the fetcher
import { useQuery } from '@tanstack/react-query';
import { fetchTasks } from '@/fetchers/task';
export function useProjectTasks(projectId: string) {
return useQuery(['tasks', projectId], () => fetchTasks(projectId), {
// Show a toast only once per query failure
onError: (err) => {
// err is already of type ApiError thanks to parseApiError
console.error('Task fetch failed', err);
},
retry: false, // Let the UI decide when to retry after showing help
});
}
Summary
- Kaneo uses
HTTPExceptionfrom Hono in the backend to signal errors with specific HTTP status codes via files likeapps/api/src/task/controllers/update-task.ts. - The frontend normalizes all errors into an
ApiErrortype usingparseApiError()fromapps/web/src/lib/error-handler.ts. - Error classification covers five types: network, CORS, auth, server, and unknown, each with dedicated troubleshooting helpers.
- UI components display user-friendly messages and actionable troubleshooting steps without exposing internal server details.
Frequently Asked Questions
How does Kaneo's backend signal errors to the frontend?
The backend throws HTTPException instances from hono/http-exception with specific status codes (400, 401, 404, 500). Controllers like apps/api/src/task/controllers/update-task.ts use these exceptions to indicate validation failures, missing resources, or permission issues. The frontend catches these HTTP responses and maps status codes to specific error categories.
What error types does the Kaneo frontend recognize?
The frontend recognizes five error types defined in apps/web/src/lib/error-handler.ts: network (connectivity failures), CORS (cross-origin configuration issues), auth (401/403 responses), server (5xx errors), and unknown (unexpected exceptions). Each type triggers specific user-facing messages and troubleshooting steps.
Where is the error handling logic located in the Kaneo codebase?
Core error handling resides in apps/web/src/lib/error-handler.ts for the frontend and various controller files like apps/api/src/task/controllers/update-task.ts for the backend. Additional utilities include apps/api/src/utils/authenticate-api-request.ts for auth errors and apps/api/src/utils/validate-dates.ts for validation logic.
How can I customize error messages in Kaneo?
Modify the parseApiError() function in apps/web/src/lib/error-handler.ts to change classification logic or error messages. For backend messages, edit the message property passed to HTTPException constructors in controller files. The getCorsTroubleshootingSteps() and getNetworkTroubleshootingSteps() functions can be extended to include custom diagnostic guidance for your deployment environment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →