# How to Handle Errors in Kaneo: Backend and Frontend Error Management Patterns

> Master error handling in Kaneo with our guide to backend HTTPExceptions and frontend ApiError types. Learn effective error management patterns for robust applications.

- Repository: [kaneo.app/kaneo](https://github.com/usekaneo/kaneo)
- Tags: best-practices
- Published: 2026-08-08

---

**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`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/task/controllers/update-task.ts), controllers validate inputs and enforce business rules before throwing specific exceptions:

```typescript
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`](https://github.com/usekaneo/kaneo/blob/main/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`](https://github.com/usekaneo/kaneo/blob/main/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`](https://github.com/usekaneo/kaneo/blob/main/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`](https://github.com/usekaneo/kaneo/blob/main/apps/web/src/lib/toast.ts).

```typescript
// 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;
  }
}

```

```typescript
// 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 `HTTPException` from Hono in the backend to signal errors with specific HTTP status codes via files like [`apps/api/src/task/controllers/update-task.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/task/controllers/update-task.ts).
- The frontend normalizes all errors into an `ApiError` type using `parseApiError()` from [`apps/web/src/lib/error-handler.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/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`](https://github.com/usekaneo/kaneo/blob/main/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`](https://github.com/usekaneo/kaneo/blob/main/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`](https://github.com/usekaneo/kaneo/blob/main/apps/web/src/lib/error-handler.ts) for the frontend and various controller files like [`apps/api/src/task/controllers/update-task.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/task/controllers/update-task.ts) for the backend. Additional utilities include [`apps/api/src/utils/authenticate-api-request.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/utils/authenticate-api-request.ts) for auth errors and [`apps/api/src/utils/validate-dates.ts`](https://github.com/usekaneo/kaneo/blob/main/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`](https://github.com/usekaneo/kaneo/blob/main/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.