Skip to content

Validation & Hono

Shared Standard Schema validation errors and drop-in Hono middleware.

@nice-code/common-errors provides a shared error domain for Standard Schema validation failures, plus Hono middleware that throws it.

Terminal window
bun add @nice-code/common-errors

Peer deps: valibot (or any Standard Schema library), hono (for the /hono subpath).

err_validation is a @nice-code/error domain. Import it to match or inspect validation errors by domain. It exposes one id — EValidator.standard_schema — with context { issues }.

import { err_validation, EValidator } from "@nice-code/common-errors";
if (err_validation.isExact(caught)) {
const hydrated = err_validation.hydrate(caught);
const { issues } = hydrated.getContext(EValidator.standard_schema);
// issues: readonly StandardSchemaV1.Issue[]
}

Import from the /hono subpath.

A drop-in replacement for @hono/standard-validator’s sValidator that throws a NiceError instead of returning a 400 when validation fails.

import { niceSValidator } from "@nice-code/common-errors/hono";
import * as v from "valibot";
const CreateUserSchema = v.object({
name: v.string(),
email: v.pipe(v.string(), v.email()),
});
app.post("/users", niceSValidator("json", CreateUserSchema), async (c) => {
const body = c.req.valid("json"); // fully typed
// ...
});

Convert the thrown error to a response in Hono’s onError:

import { castNiceError } from "@nice-code/error";
app.onError((err, c) => {
const niceError = castNiceError(err);
return c.json(niceError.toJsonObject(), niceError.httpStatusCode as any);
});

Intercepts raw @hono/standard-validator responses (the default { success: false, error: [...] } shape) and converts them into NiceError JSON responses — for when you can’t swap sValidator out directly.

import { niceCatchSValidation } from "@nice-code/common-errors/hono";
app.use(niceCatchSValidation());
// Existing sValidator usage is now intercepted automatically
app.post("/data", sValidator("json", MySchema), handler);
import { Hono } from "hono";
import { niceSValidator } from "@nice-code/common-errors/hono";
import { castNiceError } from "@nice-code/error";
import * as v from "valibot";
const app = new Hono();
app.onError((err, c) => {
const niceError = castNiceError(err);
return c.json(niceError.toJsonObject(), niceError.httpStatusCode as any);
});
const BodySchema = v.object({ message: v.string() });
app.post("/echo", niceSValidator("json", BodySchema), async (c) => {
const { message } = c.req.valid("json");
return c.json({ echo: message });
});