Skip to content

Commit

Permalink
feat: add new ValidationError system
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien-R44 committed Jan 31, 2025
1 parent 349b5ef commit 28aa0f2
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 12 deletions.
3 changes: 2 additions & 1 deletion packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"dependencies": {
"buffer": "catalog:",
"zod": "catalog:"
"zod": "catalog:",
"zod-validation-error": "^3.4.0"
}
}
32 changes: 32 additions & 0 deletions packages/utils/src/__tests__/validation-error.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { describe, expect, test } from 'vitest'
import z from 'zod'
import { ValidationError } from '../error/ValidationError'

describe('Validation error', () => {
test('basic', () => {
const schema = z.object({
name: z.string(),
age: z.number(),
object: z.object({
foo: z.object({
bar: z.discriminatedUnion('type', [
z.object({ type: z.literal('a'), a: z.string() }),
z.object({ type: z.literal('b'), b: z.number() }),
]),
}),
}),
})

const result = schema.safeParse({
object: { foo: { bar: { type: 'z', a: 123 } } },
})

const error = new ValidationError('Validation failed', result.error)
expect(error.message).toMatchInlineSnapshot(`
"[ValidationError] Validation failed
- Required at "name"
- Required at "age"
- Invalid discriminator value. Expected 'a' | 'b' at "object.foo.bar.type""
`)
})
})
18 changes: 10 additions & 8 deletions packages/utils/src/error/ValidationError.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import type z from 'zod'
import { fromError } from 'zod-validation-error'

export class ValidationError<Schema extends z.ZodTypeAny = z.ZodTypeAny> extends Error {
export class ValidationError extends Error {
public constructor(
message: string,
public readonly error?: z.ZodError<Schema>
public readonly error?: z.ZodError
) {
/**
* TODO: Before Zod, we were using some flattening logic to make the error message more readable.
* We may want to do the same thing here again.
*/
const errorDetails = JSON.stringify(error, null, 2)
super(`${message}\n${errorDetails}`)
const errorDetails = fromError(error, {
issueSeparator: '\n\t- ',
prefix: `[ValidationError] ${message}`,
prefixSeparator: '\n\t- ',
})

super(errorDetails.toString(), { cause: error })
}
}
2 changes: 1 addition & 1 deletion packages/utils/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "build",
"lib": ["ES2020", "DOM"]
"lib": ["ES2022", "DOM"]
}
}
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"compilerOptions": {
"module": "Node16",
"target": "ES2020",
"target": "ES2022",
"declaration": true,
"sourceMap": true,
"strict": true,
"skipLibCheck": true,
"noEmitOnError": true,
"lib": ["ES2020"],
"lib": ["ES2022"],
"types": [],
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
Expand Down

0 comments on commit 28aa0f2

Please sign in to comment.