Skip to content
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

Handling @fastify/type-provider-typebox schema validation errors on the frontend #1026

Open
satnamDev-Ops opened this issue May 1, 2024 · 3 comments
Labels
help wanted Extra attention is needed

Comments

@satnamDev-Ops
Copy link

Description:

I am currently using @fastify/type-provider-typebox for schema validation in a Fastify application, and I'm interested in understanding how to handle the validation errors more effectively.

Below is a simplified version of my setup:

app.ts:

export async function build(opts: FastifyOptions): Promise<FastifyInstance> {
  const app = fastify(opts)
    .setValidatorCompiler(TypeBoxValidatorCompiler)
    .withTypeProvider<TypeBoxTypeProvider>();

  // Registering routes
  app.register(user, { prefix: '/user' });
  return app;
}

user.schema.ts:

import { Type, Static } from '@fastify/type-provider-typebox';

export const UserSchema = Type.Object({
  firstName: Type.String(),
  lastName: Type.String(),
  DoB: Type.String(),
});
export type User = Static<typeof UserSchema>;

userRoute.ts:

app.post('/user', { schema: { body: UserSchema } }, 
  async (req: FastifyRequest<{Body: User}>, reply: FastifyReply) => {
    return { ...req.body };
  }
);

When there's a validation error, the error message I receive is in string format:

{
  "statusCode": 400,
  "code": "FST_ERR_VALIDATION",
  "error": "Bad Request",
  "message": "body/lastName Required property, body/DoB Required property, body/lastName Expected string, body/DoB Expected string"
}

I'm concerned about handling these error messages on the frontend as the message is in string format.

To improve this, I tried customizing the error format using the setErrorHandler method:

app.ts (with custom error format):

export async function build(opts: FastifyOptions): Promise<FastifyInstance> {
  const customErrorFormat = (
    error: FastifyError,
    request: FastifyRequest,
    reply: FastifyReply
  ) => {
   if(error.validation){
      const structuredErrors: {
        keyword: string;
        schemaErrors: FastifySchemaValidationError[];
        message: string;
      }[] = [
            {
              keyword: 'validation',
              schemaErrors: error.validation,
              message: error.message,
            },
          ];
        return structuredErrors;
    }

    return error
  }

  const app = fastify(opts)
    .setValidatorCompiler(TypeBoxValidatorCompiler)
    .setErrorHandler(customErrorFormat)
    .withTypeProvider<TypeBoxTypeProvider>();

  // Registering routes
  app.register(user, { prefix: '/user' });
  return app;
}

With this setup, I get the errors in the following format:

[
  {
    "keyword": "validation",
    "schemaErrors": [
      {
        "message": "Required property",
        "instancePath": "/lastName"
      },
      {
        "message": "Required property",
        "instancePath": "/DoB"
      },
      {
        "message": "Expected string",
        "instancePath": "/lastName"
      },
      {
        "message": "Expected string",
        "instancePath": "/DoB"
      }
    ],
    "message": "body/lastName Required property, body/DoB Required property, body/lastName Expected string, body/DoB Expected string"
  }
]

While this format is more structured, I'm still unsure if it's the right approach, and I have a few questions:

Questions:

  1. Is structuring the error message (using setErrorHandler(customErrorFormat)) in the provided format the recommended approach for handling schema validation errors?
  2. Can I customize the error messages for each instance path in the schema validation error?
  3. How do developers typically handle these issues in real-life scenarios when using schema validation?

I would appreciate any insights or advice.


@satnamDev-Ops satnamDev-Ops added the help wanted Extra attention is needed label May 1, 2024
@mcollina
Copy link
Member

mcollina commented May 2, 2024

  1. yes
  2. yes, by customizing Ajv
  3. in most modern web apps, form validation does not happen on the server. It's implemented in the client before the data is sent. It allows for a better DX.

@satnamDev-Ops
Copy link
Author

@mcollina Thank you!

yes, by customizing Ajv

Is it possible to customize errors in @fastify/type-provider-typebox? I would appreciate a small example if available.

@marcoturi
Copy link

looking into fastify-type-provider-typebox it looks it simply output the error originated from @sinclair/typebox

I would start by looking here to customize the error @satnamDev-Ops https://github.com/sinclairzx81/typebox?tab=readme-ov-file#error-function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants