Refactor errors to use @fastify/error and throw correct validation error#110
Refactor errors to use @fastify/error and throw correct validation error#110kibertoad merged 5 commits intoturkerdev:mainfrom
Conversation
- 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, |
There was a problem hiding this comment.
why can't we return details here and assert that validation error exposes enough details?
There was a problem hiding this comment.
There is no details on ResponseSerializationError.
We would now have to access it through error.cause.
edited since I stated it wrong
There was a problem hiding this comment.
that's fine, can we use that field to preserve the initial test logic?
There was a problem hiding this comment.
Done, I also made a mistake so I renamed ResponseValidationError to ResponseSerializationError since that is what it is.
There was a problem hiding this comment.
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'))
}
})
There was a problem hiding this comment.
fastify error model really isn't very flexible :-/
trying to augment errors we are getting there currently
test/response-schema.spec.ts
Outdated
| "url": "/incorrect", | ||
| }, | ||
| "error": "Internal Server Error", | ||
| "issues": [ |
There was a problem hiding this comment.
this is less useful than what we had before.
does the new error structure no longer expose the url and the method?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
|
@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 { |
There was a problem hiding this comment.
Why is this not an arrow function? All others are using an arrow function.
There was a problem hiding this comment.
only the ones that are exported
src/errors.ts
Outdated
| 500, | ||
| ); | ||
|
|
||
| export type InvalidSchemaErrorType = FastifySchemaValidationError; |
There was a problem hiding this comment.
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 & { |
|
Can I force push an alternative? |
|
@Bram-dc sure! as long as it preserves the expectations of the test |
|
this is perfect, thank you! |

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