Skip to content

onError Handler

The handleError function is an error handler for Hono applications that converts Nimbus exceptions to structured HTTP JSON responses.

Basic Usage

typescript
import { Hono } from "hono";
import { handleError } from "@nimbus/hono";

const app = new Hono();

// Register the error handler
app.onError(handleError);

Response Format

When a Nimbus exception is thrown, the handler returns a JSON response with the following structure:

json
{
    "error": "EXCEPTION_NAME",
    "message": "Human-readable error message",
    "details": { ... }
}
FieldDescription
errorThe exception name (e.g., NOT_FOUND, INVALID_INPUT)
messageThe error message provided when throwing the exception
detailsOptional additional details (only included if provided)

Status Code Mapping

The HTTP status code is taken directly from the exception's statusCode property:

ExceptionStatus CodeResponse error
GenericException500GENERIC_EXCEPTION
InvalidInputException400INVALID_INPUT
NotFoundException404NOT_FOUND
UnauthorizedException401UNAUTHORIZED
ForbiddenException403FORBIDDEN
Custom exceptions(custom)(custom name)

Logging Behavior

The handler logs errors differently based on the status code:

Status CodeLog LevelDescription
5xxerrorServer errors that need investigation
4xxdebugClient errors, typically expected
UnhandledcriticalNon-Nimbus errors, unexpected failures

Example: Exception Handling

typescript
import { Hono } from "hono";
import { handleError } from "@nimbus/hono";
import { NotFoundException, InvalidInputException } from "@nimbus/core";

const app = new Hono();

app.get("/users/:id", async (c) => {
    const user = await findUser(c.req.param("id"));

    if (!user) {
        throw new NotFoundException("User not found", {
            userId: c.req.param("id"),
        });
    }

    return c.json(user);
});

app.post("/users", async (c) => {
    const body = await c.req.json();

    if (!body.email) {
        throw new InvalidInputException("Email is required", {
            field: "email",
        });
    }

    const user = await createUser(body);
    return c.json(user, 201);
});

app.onError(handleError);

Response Examples

NotFoundException (404):

json
{
    "error": "NOT_FOUND",
    "message": "User not found",
    "details": {
        "userId": "123"
    }
}

InvalidInputException (400):

json
{
    "error": "INVALID_INPUT",
    "message": "Email is required",
    "details": {
        "field": "email"
    }
}

Unhandled Error (500):

json
{
    "error": "INTERNAL_SERVER_ERROR"
}

Complete Application Setup

typescript
import { Hono } from "hono";
import { correlationId, handleError, logger } from "@nimbus/hono";
import { setupLogger, parseLogLevel } from "@nimbus/core";

setupLogger({
    logLevel: parseLogLevel(process.env.LOG_LEVEL),
});

const app = new Hono();

app.use(correlationId());
app.use(logger({ enableTracing: true }));

// Your routes here
app.get("/health", (c) => c.json({ status: "ok" }));

// Error handler must be registered last
app.onError(handleError);

export default app;