Skip to content

Commit

Permalink
Correctly process paths in map_of and record_of. Do not swallow a…
Browse files Browse the repository at this point in the history
…nd use indent for nested `one_of` error messages.
  • Loading branch information
azasypkin committed Oct 28, 2019
1 parent f868fa6 commit 97a55c9
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 7 deletions.
7 changes: 4 additions & 3 deletions packages/kbn-config-schema/src/errors/validation_error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@
import { SchemaError, SchemaTypeError, SchemaTypesError } from '.';

export class ValidationError extends SchemaError {
public static extractMessage(error: SchemaTypeError, namespace?: string) {
private static extractMessage(error: SchemaTypeError, namespace?: string, level?: number) {
const path = typeof namespace === 'string' ? [namespace, ...error.path] : error.path;

let message = error.message;
if (error instanceof SchemaTypesError) {
const indentLevel = level || 0;
const childErrorMessages = error.errors.map(childError =>
ValidationError.extractMessage(childError, namespace)
ValidationError.extractMessage(childError, namespace, indentLevel + 1)
);

message = `${message}\n${childErrorMessages
.map(childErrorMessage => `- ${childErrorMessage}`)
.map(childErrorMessage => `${' '.repeat(indentLevel)}- ${childErrorMessage}`)
.join('\n')}`;
}

Expand Down
20 changes: 20 additions & 0 deletions packages/kbn-config-schema/src/types/map_of_type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,23 @@ test('object within mapOf', () => {

expect(type.validate(value)).toEqual(expected);
});

test('error preserves full path', () => {
const type = schema.object({
grandParentKey: schema.object({
parentKey: schema.mapOf(schema.string({ minLength: 2 }), schema.number()),
}),
});

expect(() =>
type.validate({ grandParentKey: { parentKey: { a: 'some-value' } } })
).toThrowErrorMatchingInlineSnapshot(
`"[grandParentKey.parentKey.key(\\"a\\")]: value is [a] but it must have a minimum length of [2]."`
);

expect(() =>
type.validate({ grandParentKey: { parentKey: { ab: 'some-value' } } })
).toThrowErrorMatchingInlineSnapshot(
`"[grandParentKey.parentKey.ab]: expected value of type [number] but got [string]"`
);
});
2 changes: 1 addition & 1 deletion packages/kbn-config-schema/src/types/map_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class MapOfType<K, V> extends Type<Map<K, V>> {
return `expected value of type [Map] or [object] but got [${typeDetect(value)}]`;
case 'map.key':
case 'map.value':
const childPathWithIndex = reason.path.slice();
const childPathWithIndex = path.slice();
childPathWithIndex.splice(
path.length,
0,
Expand Down
17 changes: 17 additions & 0 deletions packages/kbn-config-schema/src/types/one_of_type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,20 @@ test('fails if not matching literal', () => {

expect(() => type.validate('bar')).toThrowErrorMatchingSnapshot();
});

test('fails if nested union type fail', () => {
const type = schema.oneOf([
schema.oneOf([schema.boolean()]),
schema.oneOf([schema.oneOf([schema.object({}), schema.number()])]),
]);

expect(() => type.validate('aaa')).toThrowErrorMatchingInlineSnapshot(`
"types that failed validation:
- [0]: types that failed validation:
- [0]: expected value of type [boolean] but got [string]
- [1]: types that failed validation:
- [0]: types that failed validation:
- [0]: expected a plain object value, but found [string] instead.
- [1]: expected value of type [number] but got [string]"
`);
});
20 changes: 20 additions & 0 deletions packages/kbn-config-schema/src/types/record_of_type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,23 @@ test('object within recordOf', () => {

expect(type.validate(value)).toEqual({ foo: { bar: 123 } });
});

test('error preserves full path', () => {
const type = schema.object({
grandParentKey: schema.object({
parentKey: schema.recordOf(schema.string({ minLength: 2 }), schema.number()),
}),
});

expect(() =>
type.validate({ grandParentKey: { parentKey: { a: 'some-value' } } })
).toThrowErrorMatchingInlineSnapshot(
`"[grandParentKey.parentKey.key(\\"a\\")]: value is [a] but it must have a minimum length of [2]."`
);

expect(() =>
type.validate({ grandParentKey: { parentKey: { ab: 'some-value' } } })
).toThrowErrorMatchingInlineSnapshot(
`"[grandParentKey.parentKey.ab]: expected value of type [number] but got [string]"`
);
});
2 changes: 1 addition & 1 deletion packages/kbn-config-schema/src/types/record_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class RecordOfType<K extends string, V> extends Type<Record<K, V>> {
return `expected value of type [object] but got [${typeDetect(value)}]`;
case 'record.key':
case 'record.value':
const childPathWithIndex = reason.path.slice();
const childPathWithIndex = path.slice();
childPathWithIndex.splice(
path.length,
0,
Expand Down
4 changes: 3 additions & 1 deletion packages/kbn-config-schema/src/types/union_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ export class UnionType<RTS extends Array<Type<any>>, T> extends Type<T> {
const childPathWithIndex = e.path.slice();
childPathWithIndex.splice(path.length, 0, index.toString());

return new SchemaTypeError(e.message, childPathWithIndex);
return e instanceof SchemaTypesError
? new SchemaTypesError(e.message, childPathWithIndex, e.errors)
: new SchemaTypeError(e.message, childPathWithIndex);
})
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ describe('copy to space', () => {
expect(() =>
resolveConflicts.routeValidation.body!.validate(payload)
).toThrowErrorMatchingInlineSnapshot(
`"[key(\\"invalid-space-id!@#$%^&*()\\")]: Invalid space id: invalid-space-id!@#$%^&*()"`
`"[retries.key(\\"invalid-space-id!@#$%^&*()\\")]: Invalid space id: invalid-space-id!@#$%^&*()"`
);
});

Expand Down

0 comments on commit 97a55c9

Please sign in to comment.