-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@hono/zod-openapi: Global error handler #323
Comments
Hi, I actually asked this question in the discussions: https://github.com/orgs/honojs/discussions/1803 I wonder if the |
Thanks for pointing me to that issue! Having validation errors end up in the global error handler would actually be my preferred way as well. 😃 I do this in all my Express apps. |
Hono@v4 now throws an Unfortunately, this does not seem to apply to the validation provided by {
"success": false,
"error": {
// ...
}
} @yusukebe Is this intended behavior? Maybe I'm doing something wrong… Or does zod-openapi needs to be patched as well? |
Hi @soulchild
Perhaps there is a difference in understanding between you and me. In v4, now, errors are thrown when app.post(
'/post',
zValidator('json', schema, (result, c) => {
if (!result.success) {
return c.text(`${result.data.id} is invalid!`, 400)
}
const data = result.data
return c.text(`${data.id} is valid!`)
}),
//...
) So please use hooks for zod-openapi, too. https://github.com/honojs/middleware/tree/main/packages/zod-openapi#handling-validation-errors |
Or, and this is just an idea, you could throw a custom error in the |
@yusukebe That's actually what I'm currently doing. 😄 To not copy and paste my lib/hono.tsexport const honoApp = () =>
new OpenAPIHono<{ Variables: { user: User | null } }>({
defaultHook: (result) => {
if (result.success) {
return;
}
const err = new HTTPException(422, {
message: 'Validation failed',
});
err.cause = result.error.errors;
throw err;
},
}); In my dedicated route files, I'm using the routes/users.tsimport { honoApp } from '@/lib/hono.js';
export const userRoutes = honoApp();
userRoutes.openapi(…) routes/other.tsimport { honoApp } from '@/lib/hono.js';
export const otherRoutes = honoApp();
otherRoutes.openapi(…) Then I register all sub-routes in my routes entry-point file: routes/index.tsimport { honoApp } from '@/lib/hono.js';
export const routes = honoApp();
routes.route('/users', usersRoutes);
routes.route('/other', otherRoutes); which is then used in my app module: app.tsimport { routes } from '@/routes/index.js';
import { honoApp } from '@/lib/hono.js';
const app = honoApp();
app.route('/api', routes); Is that how you would go about having a unified I think it'd be nice if we could put the Sorry for the lengthy post and thank you for always being very responsive and helpful! 🙏 |
I think your way is the best way! I think it is good to throw an HTTPException with 400 or 422 when a validation error occurs, as you did. The reason we didn't do it that way is that we didn't want the user to handle it with However, I think either would be good! |
Does this setup support AWS API Gateway and Lambda integration? Here's what I've implemented: const send = new OpenAPIHono<{ Bindings: Bindings }>({
defaultHook: (result, c) => {
if (result.success) {
return;
}
return c.json({ success: false, errors: result.error.errors }, { status: 400 });
},
}); However, it's not functioning as expected; instead, it throws an error. Unfortunately, this error isn't being propagated to the API consumer. They only receive a generic "Internal Server Error" message. Upon inspecting the CloudWatch logs, I found the following error:
My goal is to have this error message propagate to the end user or API consumer so they can understand what's going wrong. |
I just started playing around with Hono for the purpose of building a RESTful API with its zod-openapi middleware and so far I'm really digging it. 👍
One thing I was unable to accomplish, was having my routes split into dedicated modules/routers AND override the default validation handler in one place (my top-level application module) as suggested here:
hello-world.ts
app.ts
The
defaultHook
only triggers for routes directly applied to theapp
instance and not for the routes defined inhelloWorldRouter
.I could put the defaultHook in a dedicated function and use it in all my route modules when instantiating the
OpenAPIHono()
class, but IMHO that's too easy to forget and could lead to inconsistent error handling. A better alternative would be creating my own custom class which wrapsOpenAPIHono
and always injects thedefaultHook
, but before I do that I wanted to ask whether the current behavior is intentional or maybe a bug?Thank you for creating Hono and any hints which might help me solve the issue.
The text was updated successfully, but these errors were encountered: