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.
bun add @nice-code/common-errorsPeer deps: valibot (or any Standard Schema library), hono (for the /hono subpath).
The validation error domain
Section titled “The validation error domain”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[]}Hono middleware
Section titled “Hono middleware”Import from the /hono subpath.
niceSValidator(target, schema)
Section titled “niceSValidator(target, schema)”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);});niceCatchSValidation()
Section titled “niceCatchSValidation()”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 automaticallyapp.post("/data", sValidator("json", MySchema), handler);Full example
Section titled “Full example”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 });});