Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/andrewvo89/zod-error
Utilities to format and customize Zod error messages
https://github.com/andrewvo89/zod-error
error nodejs typescript validation zod
Last synced: about 1 month ago
JSON representation
Utilities to format and customize Zod error messages
- Host: GitHub
- URL: https://github.com/andrewvo89/zod-error
- Owner: andrewvo89
- License: mit
- Created: 2022-07-12T10:43:10.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-02-22T11:37:37.000Z (almost 2 years ago)
- Last Synced: 2024-11-25T04:41:53.590Z (about 2 months ago)
- Topics: error, nodejs, typescript, validation, zod
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/zod-error
- Size: 103 KB
- Stars: 50
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome - andrewvo89/zod-error - Utilities to format and customize Zod error messages (TypeScript)
README
Zod Error
[![Status](https://img.shields.io/badge/status-active-blue)](https://github.com/andrewvo89/zod-error)
[![GitHub Issues](https://img.shields.io/github/issues/andrewvo89/zod-error?color=blue)](https://github.com/andrewvo89/zod-error/issues)
[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/andrewvo89/zod-error?color=blue)](https://github.com/andrewvo89/zod-error/pulls)
[![License](https://img.shields.io/github/license/andrewvo89/zod-error?color=blue)](/LICENSE)---
Utilities to format and customize Zod error messages.
## Table of Contents
- [About](#about)
- [Installation](#installation)
- [Usage](#usage)
- [Authors](#authors)
- [Acknowledgments](#acknowledgements)## About
Zod Error converts and formats Zod Issues into a customizable error message string that can be consumed by various applications such as front end error message modals or api error messages.
### Basic Usage
Zod Error converts an array of Zod Issues that look like this:
```ts
[
{
code: 'invalid_type',
expected: 'string',
received: 'undefined',
path: ['name'],
message: 'Required',
},
{
code: 'invalid_type',
expected: 'string',
received: 'number',
path: ['pets', 1],
message: 'Expected string, received number',
},
];
```into this:
```
Error #1: Code: invalid_type ~ Path: name ~ Message: Required | Error #2: Code: invalid_type ~ Path: pets[1] ~ Message: Expected string, received number
```## Installation
Install the package using your favorite package manager:
```
npm install zod-error
yarn add zod-error
pnpm add zod-error
```## Usage
### Message Format
```
🕓 2022-07-14T20:19:52.290Z ~ Error #1: Code: invalid_type ~ Path: ratings[0].speed ~ Message: Expected number, received string 🔥 Error #2: Code: invalid_enum_value ~ Path: position ~ Message: Invalid enum value. Expected 'C' | 'PF' | 'SF' | 'SG' | 'PG', received 'Center'🔚
```
| Value | Description |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| `🕓 2022-07-14T20:19:15.660Z ~` | Prefix |
| `~` | Component delimiter |
| `Error #1:` | Added using `options.transform()` |
| `Code: ` | Code label |
| `invalid_type` | Code value |
| `Path: ` | Path label |
| `ratings[0].speed` | Path value |
| `Message: ` | Message label |
| `Expected number, received string` | Message value |
| `🔥` | Error delimiter |
| `Error #2: Code: invalid_enum_value ~ Path: position ~ Message: Invalid enum value. Expected 'C' \| 'PF' \| 'SF' \| 'SG'\| 'PG', received 'Center'` | Error from second ZodIssue from Issues array input |
| `🔚` | Suffix |### Options
Error messages are completely customizable from label names to delimiters, prefixes, suffixes and the inclusion/exclusion of components (code, path, message). An options argument can be passed to any Zod Error function as the last argument to customize the error message.
| Property | Value | Description |
| ---------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------- |
| code? | [CodeOptions](#codeoptions) | Options to customize the code component of the error message. |
| delimiter? | [DelimiterOptions](#delimiteroptions) | Set the delimiter between error messages and between components. |
| maxErrors? | number | Maximum amount of error messages to display in final concatenated string. |
| message? | [MessageOptions](#messageoptions) | Options to customize the message component of the error message. |
| path? | [PathOptions](#pathoptions) | Options to customize the code path of the error message. |
| prefix? | string | Add a prefix to the start of the final concatenated message. |
| suffix? | string | Add a suffix to the end of the final concatenated string. |
| transform? | (params: [TransformErrorParams](#transformerrorparams)) => string | A custom function to transform the format of each error message. |### CodeOptions
| Property | Value | Description |
| ---------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| enabled | boolean | Display or hide the code component of the error message. Defaults to `true`. |
| label? | string \| null | Set a custom label. Defaults to `Code: `. Only available if `enabled` is `true`. |
| transform? | (params: [TransformComponentParams](#transformcomponentparams)) => string | A custom function to transform the format of the code component. Only available if `enabled` is `true`. |### DelimiterOptions
| Property | Value | Description |
| ---------- | ------ | --------------------------------------------------------------------------------------------- |
| component? | string | The delimiter between each component during the concatentation process. Defaults to `~`. |
| error? | string | The delimiter between each error message during the concatentation process. Defaults to `\|`. |### MessageOptions
| Property | Value | Description |
| ---------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| enabled | boolean | Display or hide the message component of the error message. Defaults to `true`. |
| label? | string \| null | Set a custom label. Defaults to `Message: `. Only available if `enabled` is `true`. |
| transform? | (params: [TransformComponentParams](#transformcomponentparams)) => string | A custom function to transform the format of the message component. Only available if `enabled` is `true`. |### PathOptions
| Property | Value | Description |
| -------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| arraySquareBrackets? | boolean | Adds square brackets around index number in the path. Only available if `enabled` is `true` and `type` is `objectNotation` or `breadcrumbs`. Defaults to `true`. |
| delimiter? | string | Set a custom delimeter between each path element. Only available if `enabled` is `true` and `type` is `breadcrumbs`. Defaults to `>`. |
| enabled | boolean | Display or hide the path component of the error message. Defaults to `true`. |
| label? | string \| null | Set a custom label. Defaults to `Message: `. Only available if `enabled` is `true`. |
| transform? | (params: [TransformComponentParams](#transformcomponentparams)) => string | A custom function to transform the format of the message component. Only available if `enabled` is `true`. |
| type | 'objectNotation' \| 'zodPathArray' \| 'breadcrumbs' | Sets the style of the path string.
objectNotation = car.wheels[1].tyre
zodPathArray = ["car", "wheels", 1, "tyre"]
breadcrumbs = car > wheels > [1] > tyre. |### TransformComponentParams
| Property | Value | Description |
| --------- | ------ | ----------------------------------------------------------------- |
| component | string | The transformed component string. Defaults to `${label}${value}`. |
| label | string | The label of the component. |
| value | string | The value of the component. |### TransformErrorParams
| Property | Value | Description |
| ---------------- | ---------- | ------------------------------------------------------------------------- |
| codeComponent | string | The transformed code component string. Defaults to `${label}${value}`. |
| errorMessage | string | The transformed error message consisting of all components concatentated. |
| index | string | The index of the current error message. |
| issue | z.ZodIssue | The original ZodIssue object. |
| messageComponent | string | The transformed message component string. Defaults to `${label}${value}`. |
| pathComponent | string | The transformed path component string. Defaults to `${label}${value}`. |### Examples
There are 6 ways to consume Zod Error. `generateErrorMessage()`, `generateError()`, `parse()`, `parseAsync()`, `safeParse()` and `safeParseAsync()`.
#### `generateErrorMessage(issues: z.ZodIssue[], options?: ErrorMessageOptions): string`
Formats an array of Zod Issues as a result of `z.parse()`, `z.parseAsync()`, `z.safeParse()` or `z.safeParseAsync()` and outputs as a single string. Multiple errors are concatenated into a single readable string.
```ts
import { generateErrorMessage, ErrorMessageOptions } from 'zod-error';
import { z } from 'zod';enum Color {
Red = 'Red',
Blue = 'Blue',
}const options: ErrorMessageOptions = {
delimiter: {
error: ' 🔥 ',
},
transform: ({ errorMessage, index }) => `Error #${index + 1}: ${errorMessage}`,
};const schema = z.object({
color: z.nativeEnum(Color),
shape: z.string(),
size: z.number().gt(0),
});const data = {
color: 'Green',
size: -1,
};const result = schema.safeParse(data);
if (!result.success) {
const errorMessage = generateErrorMessage(result.error.issues, options);
throw new Error(errorMessage);
}
```Error Message:
```
Error #1: Code: invalid_enum_value ~ Path: color ~ Message: Invalid enum value. Expected 'Red' | 'Blue', received 'Green' 🔥 Error #2: Code: invalid_type ~ Path: shape ~ Message: Required 🔥 Error #3: Code: too_small ~ Path: size ~ Message: Number must be greater than 0
```#### `generateError(issues: z.ZodIssue[], options?: ErrorMessageOptions): Error`
Formats an array of Zod Issues as a result of `z.parse()`, `z.parseAsync()`, `z.safeParse()` or `z.safeParseAsync()` and outputs as a JavaScript Error object. Multiple errors are concatenated into a single readable string.
```ts
import { ErrorMessageOptions, generateError } from 'zod-error';
import { z } from 'zod';const options: ErrorMessageOptions = {
maxErrors: 2,
delimiter: {
component: ' - ',
},
path: {
enabled: true,
type: 'zodPathArray',
label: 'Zod Path: ',
},
code: {
enabled: false,
},
message: {
enabled: true,
label: '',
},
};const schema = z.object({
dates: z.object({
purchased: z.date(),
fulfilled: z.date(),
}),
item: z.string(),
price: z.number(),
});const data = {
dates: { purchased: 'yesterday' },
item: 1,
price: '1,000',
};try {
schema.parse(data);
} catch (error) {
const genericError = generateError(error, options);
throw genericError;
}
```Error Message:
```
Zod Path: ["dates", "purchased"] - Expected date, received string | Zod Path: ["dates", "fulfilled"] - Required
```#### `parse(schema: T, data: unknown, options?: ErrorMessageOptions): T['_output']`
Replaces Zod's `.parse()` function by replacing Zod's `ZodError` with a generic JavaScript `Error` object where the custom formatted message can be accessed on `error.message`.
```ts
import { ErrorMessageOptions, parse } from 'zod-error';
import { z } from 'zod';const options: ErrorMessageOptions = {
delimiter: {
error: ' ',
},
path: {
enabled: true,
type: 'objectNotation',
transform: ({ label, value }) => `<${label}: ${value}>`,
},
code: {
enabled: true,
transform: ({ label, value }) => `<${label}: ${value}>`,
},
message: {
enabled: true,
transform: ({ label, value }) => `<${label}: ${value}>`,
},
transform: ({ errorMessage }) => `👉 ${errorMessage} 👈`,
};const schema = z.object({
animal: z.enum(['🐶', '🐱', '🐵']),
quantity: z.number().gte(1),
});const data = {
animal: '🐼',
quantity: 0,
};try {
const safeData = parse(schema, data, options);
/**
* Asynchronous version
* const safeData = await parseAsync(schema, data, options);
*/
} catch (error) {
/**
* Replaces ZodError with a JavaScript
* Error object with custom formatted message.
*/
if (error instanceof Error) {
console.error(error.message);
}
}
```Error Message:
```
👉 ~ ~ 👈 👉 ~ ~ 👈
```Note:
> If your schema contains an async `.refine()` or `.transform()` function, use `parseAsync()` instead.
#### `safeParse(schema: T, data: unknown, options?: ErrorMessageOptions): SafeParseReturnType If your schema contains an async `.refine()` or `.transform()` function, use `safeParseAsync()` instead.
## Authors
- [@andrewvo89](https://github.com/andrewvo89) - Idea & Initial work.
See also the list of [contributors](https://github.com/andrewvo89/zod-error/contributors) who participated in this project.
## Acknowledgements
- [Zod](https://zod.dev/) for an amazing validation library.