Reference
yieldless/router
Tuple-returning route handlers with HTTP error mapping.
yieldless/router turns tuple-native handlers into Hono-style JSON handlers.
Exports
honoHandler(handler, options)
Error classes
HttpErrorBadRequestErrorUnauthorizedErrorForbiddenErrorNotFoundErrorConflictErrorValidationError
Handler shape
type TupleRouteHandler<Context, Data, ErrorType = Error> = (context: Context) => PromiseLike<SafeResult<Data, ErrorType>> | SafeResult<Data, ErrorType>
Example
import { honoHandler, NotFoundError } from "yieldless/router";
export const getRepository = honoHandler(async (c) => {
const repo = await findRepository(c.req.param("id"));
if (repo === null) {
return [new NotFoundError("Repository not found"), null];
}
return [null, repo];
});What the adapter does
| Input | Output |
|---|---|
| Success tuple | context.json(data, status) |
HttpError instance | Configured status code |
| Unknown error | Generic 500 |
options.mapError() | Normalize custom domain errors into HttpError |
When this module is enough
If your framework only needs a json() method on the context, this adapter is usually enough.
Good
Return domain or HTTP errors as tuples and let the adapter serialize them.
export const getUser = honoHandler(async (c) => {
const [error, user] = await loadUser(c.req.param("id"));
if (error) return [error, null];
if (user === null) {
return [new NotFoundError("User not found"), null];
}
return [null, user];
});Use mapError() when your domain errors are not already HttpError instances.
honoHandler(handler, {
mapError: (error) =>
error instanceof DomainValidationError
? new BadRequestError(error.message)
: error,
});Avoid
Do not throw routine route failures just to let a global error handler find them later.
if (user === null) {
throw new Error("User not found");
}For expected misses, return a tuple error with an explicit HTTP shape.