Zod parse with custom error in Express
If you use Typescript then zod is a great data parser to try. Here is a quick method that will allow you to return a custom error message when a zod parser fails to parse a schema.
Add type definitions
Add a folder called "type-definitions" to your project. In that folder create a file called "express.d.ts". This is where you will put your custom types.
Save the following to zod-parse.ts
:
import type { Request } from "express";
import { AnyZodObject, ZodError, z } from "zod";
import { BadRequestError } from "./bad-request-error.js";
export async function zParse<T extends AnyZodObject>(
schema: T,
req: Request
): Promise<z.infer<T>> {
try {
// have to await this here to convert this error to a BadRequestError
return await schema.parseAsync(req);
} catch (error) {
if (error instanceof ZodError) {
throw new BadRequestError(error.message);
}
throw new BadRequestError(JSON.stringify(error));
}
}
And now use it in your routes like this:
import { z } from "zod";
import { zParse } from "../zod-parse.ts";
export const handleSomeRequest = (req, res, done) => {
const schema = z.object({
name: z.string().min(3).max(255),
email: z.string().email(),
password: z.string().min(8).max(255),
});
// this will throw a BadRequestError if the schema fails to parse
// The result is a perfectly typed object
const { name, email, password } = await zParse(schema, req);
// do something with the data
};
This is a nice way to convert Express request.body data into a typed object. If the data fails to parse then a BadRequestError is thrown with a custom error message.
I hope this helps!