mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-03-21 14:47:12 +01:00
feat(schema-utils): add better error handling
This commit is contained in:
13
packages/schema-utils/src/errors.ts
Normal file
13
packages/schema-utils/src/errors.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export class InvalidParameter extends Error {
|
||||
field?: string;
|
||||
|
||||
constructor(reason: string, field: string, value?: any) {
|
||||
let message = `Invalid parameter`;
|
||||
message += ` "${field.substring(1)}"`;
|
||||
message += ` (= ${JSON.stringify(value)})`;
|
||||
message += `: ${reason.replace(/'/g, '"')}`;
|
||||
super(message);
|
||||
this.name = 'InvalidParameter';
|
||||
this.field = field;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { Value } from '@sinclair/typebox/value';
|
||||
import { Mixin } from 'ts-mixer';
|
||||
|
||||
import { ArrayBufferBuilder, BufferBuilder, KeyofEnumBuilder, UintBuilder } from './custom-types';
|
||||
import { InvalidParameter } from './errors';
|
||||
|
||||
class CustomTypeBuilder extends Mixin(
|
||||
JavaScriptTypeBuilder,
|
||||
@@ -16,9 +17,10 @@ export function Validate<T extends TSchema>(schema: T, value: unknown): value is
|
||||
return Value.Check(schema, value);
|
||||
}
|
||||
export function Assert<T extends TSchema>(schema: T, value: unknown): asserts value is Static<T> {
|
||||
const result = Value.Check(schema, value);
|
||||
if (!result) {
|
||||
throw new Error('Invalid value');
|
||||
const errors = Value.Errors(schema, value);
|
||||
const error = errors.First();
|
||||
if (error) {
|
||||
throw new InvalidParameter(error.message, error.path, error.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
68
packages/schema-utils/tests/errors.test.ts
Normal file
68
packages/schema-utils/tests/errors.test.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Type, Assert } from '../src/index';
|
||||
import { InvalidParameter } from '../src/errors';
|
||||
|
||||
describe('Assert', () => {
|
||||
it('should not throw an error if matches schema', () => {
|
||||
const schema = Type.Object({ type: Type.String() });
|
||||
const value = { type: 'string' };
|
||||
expect(() => Assert(schema, value)).not.toThrow();
|
||||
});
|
||||
|
||||
it('acts as a type guard', () => {
|
||||
const schema = Type.Object({ type: Type.String() });
|
||||
const value = { type: 'string' };
|
||||
Assert(schema, value);
|
||||
// @ts-expect-error
|
||||
value.type = 123;
|
||||
});
|
||||
|
||||
it('should throw if type is mismateched', () => {
|
||||
const schema = Type.Object({ type: Type.Number() });
|
||||
const value = { type: 'string' };
|
||||
expect(() => Assert(schema, value)).toThrow(InvalidParameter);
|
||||
// Check error message
|
||||
try {
|
||||
Assert(schema, value);
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('Invalid parameter "type" (= "string"): Expected number');
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw if required field is missing', () => {
|
||||
const schema = Type.Object({ type: Type.Number() });
|
||||
const value = {};
|
||||
expect(() => Assert(schema, value)).toThrow(InvalidParameter);
|
||||
// Check error message
|
||||
try {
|
||||
Assert(schema, value);
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('Invalid parameter "type" (= undefined): Required property');
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw in case of custom types', () => {
|
||||
const schema = Type.Object({ type: Type.Uint() });
|
||||
const value = { type: 'xyz' };
|
||||
expect(() => Assert(schema, value)).toThrow(InvalidParameter);
|
||||
// Check error message
|
||||
try {
|
||||
Assert(schema, value);
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('Invalid parameter "type" (= "xyz"): Expected kind "Uint"');
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw when conditions are not met', () => {
|
||||
const schema = Type.Object({ type: Type.String({ minLength: 3 }) });
|
||||
const value = { type: 'A' };
|
||||
expect(() => Assert(schema, value)).toThrow(InvalidParameter);
|
||||
// Check error message
|
||||
try {
|
||||
Assert(schema, value);
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual(
|
||||
'Invalid parameter "type" (= "A"): Expected string length greater or equal to 3',
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user