boywithkeyboard-archive / cheetah1

A framework for the modern web. (NO LONGER MAINTAINED)
https://cheetah.mod.land
Apache License 2.0
192 stars 1 forks source link

include validation errors in the response body #200

Open TheYuriG opened 1 year ago

TheYuriG commented 1 year ago

I need to be able to retrieve failed network requests that fail to pass through Zod's validation.

Right now, it seems to return default 400 BAD REQUEST responses by default, but I prefer to know why those requests failed, so I can return that data to the browser and display alerts for all their errors, in case they manage to get through the frontend validation somehow.

I'm using zod as a validation middleware before the response is sent. This is my code:

app.put(
  //path
  "/register",
  //validation
  {
    body: z.object({
      username: z.string({
        required_error: "Name is required",
        invalid_type_error: "Name must be a string",
      }).min(6, { message: "Must be 6 or more characters long" }),
      email: z.string().email({ message: "Invalid email address" }),
      password: z.string({
        required_error: "Password is required",
        invalid_type_error: "Password must be a string",
      }).min(8, { message: "Password must be 8 or more characters long" }),
      confirmPassword: z.string({
        required_error: "Password confirmation is required",
        invalid_type_error: "Password confirmation must be a string",
      }).min(8, {
        message: "Password confirmation must be 8 or more characters long",
      }),
    }),
  },
  // response
  async (c) => {
    const reqBody = await c.req.body();
    console.log("body:", reqBody);
  },
);

When an error happens, the response is sent before reaching the response block.

TheYuriG commented 1 year ago

I ended up getting it to work by moving the validation to the response function as follows:


app.put(
  // request path
  "/register",
  // response
  async (c) => {
    // zod validation
    const zodValidation = z.object({
      username: z.string({
        required_error: "Name is required",
        invalid_type_error: "Name must be a string",
      }).min(6, { message: "Must be 6 or more characters long" }),
      email: z.string().email({ message: "Invalid email address" }),
      password: z.string({
        required_error: "Password is required",
        invalid_type_error: "Password must be a string",
      }).min(8, { message: "Password must be 8 or more characters long" }),
      confirmPassword: z.string({
        required_error: "Password confirmation is required",
        invalid_type_error: "Password confirmation must be a string",
      }).min(8, {
        message: "Password confirmation must be 8 or more characters long",
      }),
    });

    const reqBody = await c.req.json();
    console.log(reqBody);

    try {
      console.log("validated body:", zodValidation.parse(reqBody));
    } catch ({ issues }) {
      console.log("issues:", issues);
    }
  },
);

Regardless, I would prefer if this was passed to the function by default instead so I can focus on the core logic rather than also doing the parsing myself.

boywithkeyboard commented 1 year ago

This will definitely be supported starting with version v2.0!