domains / app-frameworks / honojs/hono
Consistent exception handling
Standardize how errors are thrown, propagated, and reported across the codebase. 1. Prefer `HTTPException` over manually constructed `Response` objects when signaling an HTTP-level error, so status codes and bodies stay consistent. When a custom body/content-type is needed, build the response via the `Context` (e.g. `c.text(...)`) and pass it through...
Standardize how errors are thrown, propagated, and reported across the codebase.
- Prefer
HTTPExceptionover manually constructedResponseobjects when signaling an HTTP-level error, so status codes and bodies stay consistent. When a custom body/content-type is needed, build the response via theContext(e.g.c.text(...)) and pass it throughHTTPException’sresoption, rather than returning a rawnew Response(...)that may lack proper headers.
// Prefer
const blockError = (c: Context): HTTPException =>
new HTTPException(403, { res: c.text('Forbidden', 403) })
// Avoid
return new Response('Forbidden', { status: 403 })
-
Write clear, specific error messages. Extract reused messages into named constants (capitalized, descriptive), and when an error can have multiple valid causes/types, state them explicitly, e.g.
`unexpected key type: CryptoKey.type is ${key.type}, expected 'private' or 'secret'`. -
Never silently swallow errors. In generic error-handling wrappers, only catch the specific error types you intend to handle (e.g.
HTTPException) and re-throw everything else. If relevant, also propagate the error ontocontext.errorso downstream handlers/logging can observe it. -
When an API accepts an optional
onError/error-handling callback, define a sane default behavior (e.g.console.error) when no callback is supplied, so failures aren’t silently lost, and ensure the callback’s type signature matches the actual object passed at runtime (don’t mix up related but distinct types likeStreamingApivsSSEStreamingApi).</description>