Skip to content

Refactor errors to use @fastify/error and throw correct validation error#110

Merged
kibertoad merged 5 commits intoturkerdev:mainfrom
Bram-dc:error
Sep 25, 2024
Merged

Refactor errors to use @fastify/error and throw correct validation error#110
kibertoad merged 5 commits intoturkerdev:mainfrom
Bram-dc:error

Conversation

@Bram-dc
Copy link
Contributor

@Bram-dc Bram-dc commented Sep 24, 2024

This pull request changed the plugin to use the internal errors from fastify and also return the correct validation errors.

See official type provider: https://github.com/fastify/fastify-type-provider-typebox/blob/main/index.mts

    return {
      // Note: Here we return a FastifySchemaValidationError[] result. As of writing, Fastify
      // does not currently export this type. Future revisions should uncomment the assertion
      // below and return the full set of properties. The specified properties 'message' and
      // 'instancePath' do however result in a near equivalent error messages to Ajv.
      error: errors.map((error) => ({
        message: `${error.message}`,
        instancePath: error.path
      })) // as FastifySchemaValidationError[]
    }
  • Move ResponseValidationError class to errors.ts
  • Add InvalidSchemaError class to errors.ts
  • Update imports in core.ts to reflect new file locations
  • Update resolveSchema function in core.ts to throw InvalidSchemaError

- Move ResponseValidationError class to errors.ts
- Add InvalidSchemaError class to errors.ts
- Update imports in core.ts to reflect new file locations
- Update resolveSchema function in core.ts to throw InvalidSchemaError
return reply.code(500).send({
error: 'Internal Server Error',
message: "Response doesn't match the schema",
details: (err as unknown as ResponseValidationError).details,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can't we return details here and assert that validation error exposes enough details?

Copy link
Contributor Author

@Bram-dc Bram-dc Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no details on ResponseSerializationError.

We would now have to access it through error.cause.

edited since I stated it wrong

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's fine, can we use that field to preserve the initial test logic?

Copy link
Contributor Author

@Bram-dc Bram-dc Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I also made a mistake so I renamed ResponseValidationError to ResponseSerializationError since that is what it is.

Copy link
Contributor Author

@Bram-dc Bram-dc Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation errors can be accessed through error.validation as described in the docs.

https://fastify.dev/docs/latest/Reference/Validation-and-Serialization/#error-handling

fastify.setErrorHandler(function (error, request, reply) {
  if (error.validation) {
     reply.status(422).send(new Error('validation failed'))
  }
})

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fastify error model really isn't very flexible :-/
trying to augment errors we are getting there currently

"url": "/incorrect",
},
"error": "Internal Server Error",
"issues": [
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is less useful than what we had before.

does the new error structure no longer expose the url and the method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well we could also throw the old error here, but it is mostly for consistency. This type of error should also result in a 500 Internal server error, so I think it is not important to add the url and method to the error. The default error reporting from fastify reports these values anyways with the error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Plus you can just get those values from the error handler.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will need to check it by hand in greater detail to understand whether this is sufficient.

I am primarily concerned about getting good bugsnag entries and logs, i n c l u d i n g on the client side.

whatever solution we end up with, it should expose no less data than the current one.

@kibertoad
Copy link
Collaborator

@Bram-dc I've made some adjustments, can you please check if you are OK with them?

src/core.ts Outdated
};

const resolveSchema = (maybeSchema: z.ZodTypeAny | { properties: z.ZodTypeAny }) => {
function resolveSchema(maybeSchema: z.ZodTypeAny | { properties: z.ZodTypeAny }): ZodSchema {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not an arrow function? All others are using an arrow function.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only the ones that are exported

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay

src/errors.ts Outdated
500,
);

export type InvalidSchemaErrorType = FastifySchemaValidationError;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FastifySchemaValidationError is a different error and should not be used here.

export interface FastifySchemaValidationError {
  keyword: string;
  instancePath: string;
  schemaPath: string;
  params: Record<string, unknown>;
  message?: string;
}

src/errors.ts Outdated
500,
);

export type ResponseSerializationErrorType = FastifySchemaValidationError & {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neither here

@Bram-dc
Copy link
Contributor Author

Bram-dc commented Sep 25, 2024

Can I force push an alternative?

@kibertoad
Copy link
Collaborator

@Bram-dc sure! as long as it preserves the expectations of the test

@kibertoad
Copy link
Collaborator

this is perfect, thank you!

@kibertoad kibertoad merged commit 2e3213a into turkerdev:main Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants