From 2e3cb16f53947e4f8b6febc9f32a93725e8891a7 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Fri, 8 Mar 2024 18:18:53 -0500 Subject: [PATCH] fix: surface deepest error from failed union validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Expected union value" error message is practically useless, so I think it‘s a better DX to surface the deepest validation error (based on property path). --- src/errors/errors.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/errors/errors.ts b/src/errors/errors.ts index f81de1a6..b1784848 100644 --- a/src/errors/errors.ts +++ b/src/errors/errors.ts @@ -514,13 +514,16 @@ function* FromUndefined(schema: TUndefined, references: TSchema[], path: string, } function* FromUnion(schema: TUnion, references: TSchema[], path: string, value: any): IterableIterator { let count = 0 + let deepestError: ValueError | undefined for (const subschema of schema.anyOf) { const errors = [...Visit(subschema, references, path, value)] if (errors.length === 0) return // matched count += errors.length + const pathDepth = (error: ValueError) => error.path.split('/').length + deepestError = errors.reduce((deepestError, error) => (!deepestError || pathDepth(error) > pathDepth(deepestError) ? error : deepestError), deepestError) } if (count > 0) { - yield Create(ValueErrorType.Union, schema, path, value) + yield deepestError || Create(ValueErrorType.Union, schema, path, value) } } function* FromUint8Array(schema: TUint8Array, references: TSchema[], path: string, value: any): IterableIterator {