h3 icon indicating copy to clipboard operation
h3 copied to clipboard

feat: customizable validation errors

Open sandros94 opened this issue 5 months ago • 9 comments

resolves https://github.com/h3js/h3/issues/982

I've added an additional argument to each readValidatedBody, getValidatedQuery and getValidatedRouteParams which can be either an error object or a function that returns one. If a standard-schema is being used, then the issues array is available as an argument for the function variant.

This allows for the following custom error, which will ouput a markdown list of all the errors recorded:

import * as v from "valibot";

app.post("/", async (event) => {
  const body = await readValidatedBody(
    event,
    v.object({
      name: v.pipe(v.string(), v.minLength(3), v.maxLength(20)),
      age: v.pipe(v.number(), v.integer(), v.minValue(1)),
    }),
    {
      onError: ({ issues }) => ({
        statusText: "Custom validation error",
        message: v.summarize(issues),
      }),
    },
  );
});

I've also updated the defineValidatedHandler, which brings three more properties: bodyErrors, headersErrors and queryErrors. All allowing for either error object or function that returns one

Added two types, but I'm not super satisfied with ValidateIssues naming (I'm open for suggestions):

export type ValidateIssues = ReadonlyArray<Issue>;
export type ValidateError =
  | (() => ErrorDetails)
  | ((result: FailureResult) => ErrorDetails);

I've also made sure that if a new HTTPError is thrown during validation, its content will be directly passed as is, quite useful for non-standard-schema validations.

sandros94 avatar Jul 05 '25 12:07 sandros94

Oh, is it normal that we have a decode option for route params but not for queries? 🤔

sandros94 avatar Jul 05 '25 12:07 sandros94

Codecov Report

:x: Patch coverage is 93.33333% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/utils/internal/validate.ts 91.66% 2 Missing :warning:

:loudspeaker: Thoughts on this report? Let us know!

codecov[bot] avatar Jul 05 '25 12:07 codecov[bot]

Deploying h3dev with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9f96225
Status: ✅  Deploy successful!
Preview URL: https://69c3837d.h3dev.pages.dev
Branch Preview URL: https://feat-custom-validation-error.h3dev.pages.dev

View logs

@pi0 any update on this?

sandros94 avatar Oct 29 '25 16:10 sandros94

Hi dear @sandros94. It is in my todo list, in meantime do you have time to help on fixing merge conflicts and adressing https://github.com/h3js/h3/pull/1146#discussion_r2188235982 🙏🏼

pi0 avatar Oct 29 '25 17:10 pi0

Hi dear @sandros94. It is in my todo list, in meantime do you have time to help on fixing merge conflicts and adressing https://github.com/h3js/h3/pull/1146#discussion_r2188235982 🙏🏼

Yes absolutely! And sorry, I completely forgot about that review 😅

sandros94 avatar Oct 29 '25 19:10 sandros94

I'm terribly sorry, I didn't realize that in 1e4d72079488c1d63bcb3f82491b8559883bbb71 I did not update the docs 🙈

For now I would leave it as only { issues }, to better follow the standard-schema spec FailureResult and leave room for future expansion.

Let me know if there is anything else I should take care of

sandros94 avatar Oct 31 '25 01:10 sandros94

@sandros94 updated implementation to be more compact API. Love your opinion on latest changes.

pi0 avatar Nov 01 '25 09:11 pi0

@sandros94 updated implementation to be more compact API. Love your opinion on latest changes.

Thank you, and yes it required a bit of cleanup

sandros94 avatar Nov 01 '25 16:11 sandros94