From 6db22af044aa1181050675ff04184ccb37d38bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ad=C3=A1mek?= Date: Sun, 21 Jun 2020 15:27:35 +0200 Subject: [PATCH] feat(core): use custom errors for failHandler and metadata Closes #611 --- packages/core/src/decorators/ManyToMany.ts | 6 +- packages/core/src/decorators/ManyToOne.ts | 6 +- packages/core/src/decorators/OneToMany.ts | 6 +- packages/core/src/decorators/Property.ts | 6 +- packages/core/src/entity/EntityValidator.ts | 6 - .../core/src/metadata/MetadataDiscovery.ts | 4 +- packages/core/src/metadata/MetadataStorage.ts | 4 +- .../core/src/metadata/MetadataValidator.ts | 40 +++-- packages/core/src/utils/Configuration.ts | 4 +- .../utils/{ValidationError.ts => errors.ts} | 156 +++++++++--------- packages/core/src/utils/index.ts | 2 +- 11 files changed, 124 insertions(+), 116 deletions(-) rename packages/core/src/utils/{ValidationError.ts => errors.ts} (65%) diff --git a/packages/core/src/decorators/ManyToMany.ts b/packages/core/src/decorators/ManyToMany.ts index f15fced0194f..9556079e7a90 100644 --- a/packages/core/src/decorators/ManyToMany.ts +++ b/packages/core/src/decorators/ManyToMany.ts @@ -1,7 +1,7 @@ import { ReferenceOptions } from './Property'; -import { MetadataStorage } from '../metadata'; +import { MetadataStorage, MetadataValidator } from '../metadata'; import { Utils } from '../utils'; -import { EntityValidator, ReferenceType } from '../entity'; +import { ReferenceType } from '../entity'; import { EntityName, EntityProperty, AnyEntity } from '../typings'; import { QueryOrder } from '../enums'; @@ -13,7 +13,7 @@ export function ManyToMany( return function (target: AnyEntity, propertyName: string) { options = Utils.isObject>(entity) ? entity : { ...options, entity, mappedBy }; const meta = MetadataStorage.getMetadataFromDecorator(target.constructor); - EntityValidator.validateSingleDecorator(meta, propertyName); + MetadataValidator.validateSingleDecorator(meta, propertyName); const property = { name: propertyName, reference: ReferenceType.MANY_TO_MANY } as EntityProperty; meta.properties[propertyName] = Object.assign(property, options); }; diff --git a/packages/core/src/decorators/ManyToOne.ts b/packages/core/src/decorators/ManyToOne.ts index 7ebad780d876..aa607776b950 100644 --- a/packages/core/src/decorators/ManyToOne.ts +++ b/packages/core/src/decorators/ManyToOne.ts @@ -1,7 +1,7 @@ import { ReferenceOptions } from './Property'; -import { MetadataStorage } from '../metadata'; +import { MetadataStorage, MetadataValidator } from '../metadata'; import { Utils } from '../utils'; -import { EntityValidator, ReferenceType } from '../entity'; +import { ReferenceType } from '../entity'; import { AnyEntity, EntityName, EntityProperty } from '../typings'; export function ManyToOne( @@ -11,7 +11,7 @@ export function ManyToOne( return function (target: AnyEntity, propertyName: string) { options = Utils.isObject>(entity) ? entity : { ...options, entity }; const meta = MetadataStorage.getMetadataFromDecorator(target.constructor); - EntityValidator.validateSingleDecorator(meta, propertyName); + MetadataValidator.validateSingleDecorator(meta, propertyName); const property = { name: propertyName, reference: ReferenceType.MANY_TO_ONE } as EntityProperty; meta.properties[propertyName] = Object.assign(property, options); }; diff --git a/packages/core/src/decorators/OneToMany.ts b/packages/core/src/decorators/OneToMany.ts index a33b2e4e7b17..7bac1a0ac6d3 100644 --- a/packages/core/src/decorators/OneToMany.ts +++ b/packages/core/src/decorators/OneToMany.ts @@ -1,7 +1,7 @@ import { ReferenceOptions } from './Property'; -import { MetadataStorage } from '../metadata'; +import { MetadataStorage, MetadataValidator } from '../metadata'; import { Utils } from '../utils'; -import { EntityValidator, ReferenceType } from '../entity'; +import { ReferenceType } from '../entity'; import { QueryOrder } from '../enums'; import { EntityName, EntityProperty, AnyEntity } from '../typings'; @@ -14,7 +14,7 @@ export function createOneToDecorator( return function (target: AnyEntity, propertyName: string) { options = Utils.isObject>(entity) ? entity : { ...options, entity, mappedBy }; const meta = MetadataStorage.getMetadataFromDecorator(target.constructor); - EntityValidator.validateSingleDecorator(meta, propertyName); + MetadataValidator.validateSingleDecorator(meta, propertyName); const prop = { name: propertyName, reference } as EntityProperty; Object.assign(prop, options); diff --git a/packages/core/src/decorators/Property.ts b/packages/core/src/decorators/Property.ts index 857d99d1a382..00bf6dff5920 100644 --- a/packages/core/src/decorators/Property.ts +++ b/packages/core/src/decorators/Property.ts @@ -1,6 +1,6 @@ -import { MetadataStorage } from '../metadata'; +import { MetadataStorage, MetadataValidator } from '../metadata'; import { Utils } from '../utils'; -import { Cascade, EntityValidator, ReferenceType, LoadStrategy } from '../entity'; +import { Cascade, ReferenceType, LoadStrategy } from '../entity'; import { EntityName, EntityProperty, AnyEntity, Constructor } from '../typings'; import { Type } from '../types'; @@ -8,7 +8,7 @@ export function Property(options: PropertyOptions = {}) { return function (target: AnyEntity, propertyName: string) { const meta = MetadataStorage.getMetadataFromDecorator(target.constructor); const desc = Object.getOwnPropertyDescriptor(target, propertyName) || {}; - EntityValidator.validateSingleDecorator(meta, propertyName); + MetadataValidator.validateSingleDecorator(meta, propertyName); const name = options.name || propertyName; if (propertyName !== name && !(desc.value instanceof Function)) { diff --git a/packages/core/src/entity/EntityValidator.ts b/packages/core/src/entity/EntityValidator.ts index 6e1fa1f89835..98fcbed3c868 100644 --- a/packages/core/src/entity/EntityValidator.ts +++ b/packages/core/src/entity/EntityValidator.ts @@ -8,12 +8,6 @@ export class EntityValidator { constructor(private strict: boolean) { } - static validateSingleDecorator(meta: EntityMetadata, propertyName: string): void { - if (meta.properties[propertyName]?.reference) { - throw ValidationError.multipleDecorators(meta.className, propertyName); - } - } - validate>(entity: T, payload: any, meta: EntityMetadata): void { Object.values(meta.properties).forEach(prop => { if ([ReferenceType.ONE_TO_MANY, ReferenceType.MANY_TO_MANY].includes(prop.reference)) { diff --git a/packages/core/src/metadata/MetadataDiscovery.ts b/packages/core/src/metadata/MetadataDiscovery.ts index 0924242701ca..5123b541ad96 100644 --- a/packages/core/src/metadata/MetadataDiscovery.ts +++ b/packages/core/src/metadata/MetadataDiscovery.ts @@ -3,7 +3,7 @@ import globby from 'globby'; import chalk from 'chalk'; import { AnyEntity, Constructor, Dictionary, EntityClass, EntityClassGroup, EntityMetadata, EntityProperty } from '../typings'; -import { Configuration, Utils, ValidationError } from '../utils'; +import { Configuration, Utils, MetadataError } from '../utils'; import { MetadataValidator } from './MetadataValidator'; import { MetadataStorage } from './MetadataStorage'; import { Cascade, ReferenceType } from '../entity'; @@ -723,7 +723,7 @@ export class MetadataDiscovery { } if (!target) { - throw ValidationError.entityNotFound(name, path.replace(this.config.get('baseDir'), '.')); + throw MetadataError.entityNotFound(name, path.replace(this.config.get('baseDir'), '.')); } return target; diff --git a/packages/core/src/metadata/MetadataStorage.ts b/packages/core/src/metadata/MetadataStorage.ts index 087bc215ef61..b280afb01087 100644 --- a/packages/core/src/metadata/MetadataStorage.ts +++ b/packages/core/src/metadata/MetadataStorage.ts @@ -1,5 +1,5 @@ import { EntityMetadata, AnyEntity, Dictionary } from '../typings'; -import { Utils, ValidationError } from '../utils'; +import { MetadataError, Utils } from '../utils'; import { EntityManager } from '../EntityManager'; import { EntityHelper } from '../entity'; import { EventSubscriber } from '../events'; @@ -52,7 +52,7 @@ export class MetadataStorage { get = any>(entity: string, init = false, validate = true): EntityMetadata { if (entity && !this.metadata[entity] && validate && !init) { - throw ValidationError.missingMetadata(entity); + throw MetadataError.missingMetadata(entity); } if (!this.metadata[entity] && init) { diff --git a/packages/core/src/metadata/MetadataValidator.ts b/packages/core/src/metadata/MetadataValidator.ts index b04adb4669f2..72251c103f46 100644 --- a/packages/core/src/metadata/MetadataValidator.ts +++ b/packages/core/src/metadata/MetadataValidator.ts @@ -1,16 +1,22 @@ import { EntityMetadata, EntityProperty } from '../typings'; -import { Utils, ValidationError } from '../utils'; +import { Utils, MetadataError } from '../utils'; import { ReferenceType } from '../entity'; import { MetadataStorage } from './MetadataStorage'; export class MetadataValidator { + static validateSingleDecorator(meta: EntityMetadata, propertyName: string): void { + if (meta.properties[propertyName]?.reference) { + throw MetadataError.multipleDecorators(meta.className, propertyName); + } + } + validateEntityDefinition(metadata: MetadataStorage, name: string): void { const meta = metadata.get(name); // entities have PK if (!meta.embeddable && (!meta.primaryKeys || meta.primaryKeys.length === 0)) { - throw ValidationError.fromMissingPrimaryKey(meta); + throw MetadataError.fromMissingPrimaryKey(meta); } this.validateVersionField(meta); @@ -24,29 +30,29 @@ export class MetadataValidator { validateDiscovered(discovered: EntityMetadata[], warnWhenNoEntities: boolean): void { if (discovered.length === 0 && warnWhenNoEntities) { - throw ValidationError.noEntityDiscovered(); + throw MetadataError.noEntityDiscovered(); } const duplicates = Utils.findDuplicates(discovered.map(meta => meta.className)); if (duplicates.length > 0) { - throw ValidationError.duplicateEntityDiscovered(duplicates); + throw MetadataError.duplicateEntityDiscovered(duplicates); } // validate base entities discovered .filter(meta => meta.extends && !discovered.find(m => m.className === meta.extends)) - .forEach(meta => { throw ValidationError.fromUnknownBaseEntity(meta); }); + .forEach(meta => { throw MetadataError.fromUnknownBaseEntity(meta); }); // validate we found at least one entity (not just abstract/base entities) if (discovered.filter(meta => meta.name).length === 0 && warnWhenNoEntities) { - throw ValidationError.onlyAbstractEntitiesDiscovered(); + throw MetadataError.onlyAbstractEntitiesDiscovered(); } // check for not discovered entities discovered.forEach(meta => Object.values(meta.properties).forEach(prop => { if (prop.reference !== ReferenceType.SCALAR && !discovered.find(m => m.className === prop.type)) { - throw ValidationError.fromUnknownEntity(prop.type, `${meta.className}.${prop.name}`); + throw MetadataError.fromUnknownEntity(prop.type, `${meta.className}.${prop.name}`); } })); } @@ -54,12 +60,12 @@ export class MetadataValidator { private validateReference(meta: EntityMetadata, prop: EntityProperty, metadata: MetadataStorage): void { // references do have types if (!prop.type) { - throw ValidationError.fromWrongTypeDefinition(meta, prop); + throw MetadataError.fromWrongTypeDefinition(meta, prop); } // references do have type of known entity if (!metadata.get(prop.type, false, false)) { - throw ValidationError.fromWrongTypeDefinition(meta, prop); + throw MetadataError.fromWrongTypeDefinition(meta, prop); } } @@ -76,34 +82,34 @@ export class MetadataValidator { private validateOwningSide(meta: EntityMetadata, prop: EntityProperty, inverse: EntityProperty): void { // has correct `inversedBy` on owning side if (!inverse) { - throw ValidationError.fromWrongReference(meta, prop, 'inversedBy'); + throw MetadataError.fromWrongReference(meta, prop, 'inversedBy'); } // has correct `inversedBy` reference type if (inverse.type !== meta.name) { - throw ValidationError.fromWrongReference(meta, prop, 'inversedBy', inverse); + throw MetadataError.fromWrongReference(meta, prop, 'inversedBy', inverse); } // inversed side is not defined as owner if (inverse.inversedBy) { - throw ValidationError.fromWrongOwnership(meta, prop, 'inversedBy'); + throw MetadataError.fromWrongOwnership(meta, prop, 'inversedBy'); } } private validateInverseSide(meta: EntityMetadata, prop: EntityProperty, owner: EntityProperty): void { // has correct `mappedBy` on inverse side if (prop.mappedBy && !owner) { - throw ValidationError.fromWrongReference(meta, prop, 'mappedBy'); + throw MetadataError.fromWrongReference(meta, prop, 'mappedBy'); } // has correct `mappedBy` reference type if (owner.type !== meta.name) { - throw ValidationError.fromWrongReference(meta, prop, 'mappedBy', owner); + throw MetadataError.fromWrongReference(meta, prop, 'mappedBy', owner); } // owning side is not defined as inverse if (owner.mappedBy) { - throw ValidationError.fromWrongOwnership(meta, prop, 'mappedBy'); + throw MetadataError.fromWrongOwnership(meta, prop, 'mappedBy'); } } @@ -115,14 +121,14 @@ export class MetadataValidator { const props = Object.values(meta.properties).filter(p => p.version); if (props.length > 1) { - throw ValidationError.multipleVersionFields(meta, props.map(p => p.name)); + throw MetadataError.multipleVersionFields(meta, props.map(p => p.name)); } const prop = meta.properties[meta.versionProperty]; const type = prop.type.toLowerCase(); if (type !== 'number' && type !== 'date' && !type.startsWith('timestamp') && !type.startsWith('datetime')) { - throw ValidationError.invalidVersionFieldType(meta); + throw MetadataError.invalidVersionFieldType(meta); } } diff --git a/packages/core/src/utils/Configuration.ts b/packages/core/src/utils/Configuration.ts index 11488cbc5564..9b9894bcfbbd 100644 --- a/packages/core/src/utils/Configuration.ts +++ b/packages/core/src/utils/Configuration.ts @@ -6,7 +6,7 @@ import { CacheAdapter, FileCacheAdapter, NullCacheAdapter } from '../cache'; import { EntityFactory, EntityRepository } from '../entity'; import { AnyEntity, Constructor, Dictionary, EntityClass, EntityClassGroup, IPrimaryKey } from '../typings'; import { Hydrator, ObjectHydrator } from '../hydration'; -import { Logger, LoggerNamespace, Utils, ValidationError } from '../utils'; +import { Logger, LoggerNamespace, NotFoundError, Utils } from '../utils'; import { EntityManager } from '../EntityManager'; import { EntityOptions, EntitySchema, IDatabaseDriver, MetadataStorage } from '..'; import { Platform } from '../platforms'; @@ -31,7 +31,7 @@ export class Configuration { strict: false, // eslint-disable-next-line no-console logger: console.log.bind(console), - findOneOrFailHandler: (entityName: string, where: Dictionary | IPrimaryKey) => ValidationError.findOneFailed(entityName, where), + findOneOrFailHandler: (entityName: string, where: Dictionary | IPrimaryKey) => NotFoundError.findOneFailed(entityName, where), baseDir: process.cwd(), hydrator: ObjectHydrator, autoJoinOneToOneOwner: true, diff --git a/packages/core/src/utils/ValidationError.ts b/packages/core/src/utils/errors.ts similarity index 65% rename from packages/core/src/utils/ValidationError.ts rename to packages/core/src/utils/errors.ts index 404b56b1af84..e9b483398cbb 100644 --- a/packages/core/src/utils/ValidationError.ts +++ b/packages/core/src/utils/errors.ts @@ -34,45 +34,10 @@ export class ValidationError extends Error { return new ValidationError(msg); } - static fromMissingPrimaryKey(meta: EntityMetadata): ValidationError { - return new ValidationError(`${meta.className} entity is missing @PrimaryKey()`); - } - - static fromWrongReference(meta: EntityMetadata, prop: EntityProperty, key: keyof EntityProperty, owner?: EntityProperty): ValidationError { - if (owner) { - return ValidationError.fromMessage(meta, prop, `has wrong '${key}' reference type: ${owner.type} instead of ${meta.className}`); - } - - return ValidationError.fromMessage(meta, prop, `has unknown '${key}' reference: ${prop.type}.${prop[key]}`); - } - - static fromWrongTypeDefinition(meta: EntityMetadata, prop: EntityProperty): ValidationError { - if (!prop.type) { - return ValidationError.fromMessage(meta, prop, `is missing type definition`); - } - - return ValidationError.fromMessage(meta, prop, `has unknown type: ${prop.type}`); - } - - static fromWrongOwnership(meta: EntityMetadata, prop: EntityProperty, key: keyof EntityProperty): ValidationError { - const type = key === 'inversedBy' ? 'owning' : 'inverse'; - const other = key === 'inversedBy' ? 'mappedBy' : 'inversedBy'; - - return new ValidationError(`Both ${meta.className}.${prop.name} and ${prop.type}.${prop[key]} are defined as ${type} sides, use '${other}' on one of them`); - } - static fromMergeWithoutPK(meta: EntityMetadata): void { throw new ValidationError(`You cannot merge entity '${meta.className}' without identifier!`); } - static fromUnknownEntity(className: string, source: string): ValidationError { - return new ValidationError(`Entity '${className}' was not discovered, please make sure to provide it in 'entities' array when initializing the ORM (used in ${source})`); - } - - static fromUnknownBaseEntity(meta: EntityMetadata): ValidationError { - return new ValidationError(`Entity '${meta.className}' extends unknown base entity '${meta.extends}', please make sure to provide it in 'entities' array when initializing the ORM`); - } - static transactionRequired(): ValidationError { return new ValidationError('An open transaction is required for this operation'); } @@ -89,15 +54,6 @@ export class ValidationError extends Error { return new ValidationError(`Cannot obtain optimistic lock on unversioned entity ${meta.className}`); } - static multipleVersionFields(meta: EntityMetadata, fields: string[]): ValidationError { - return new ValidationError(`Entity ${meta.className} has multiple version properties defined: '${fields.join('\', \'')}'. Only one version property is allowed per entity.`); - } - - static invalidVersionFieldType(meta: EntityMetadata): ValidationError { - const prop = meta.properties[meta.versionProperty]; - return new ValidationError(`Version property ${meta.className}.${prop.name} has unsupported type '${prop.type}'. Only 'number' and 'Date' are allowed.`); - } - static lockFailed(entityOrName: AnyEntity | string): ValidationError { const name = Utils.isString(entityOrName) ? entityOrName : entityOrName.constructor.name; const entity = Utils.isString(entityOrName) ? undefined : entityOrName; @@ -112,38 +68,10 @@ export class ValidationError extends Error { return new ValidationError(`The optimistic lock failed, version ${expectedLockVersion} was expected, but is actually ${actualLockVersion}`, entity); } - static noEntityDiscovered(): ValidationError { - return new ValidationError('No entities were discovered'); - } - - static onlyAbstractEntitiesDiscovered(): ValidationError { - return new ValidationError('Only abstract entities were discovered, maybe you forgot to use @Entity() decorator?'); - } - - static duplicateEntityDiscovered(paths: string[]): ValidationError { - return new ValidationError(`Duplicate entity names are not allowed: ${paths.join(', ')}`); - } - - static entityNotFound(name: string, path: string): ValidationError { - return new ValidationError(`Entity '${name}' not found in ${path}`); - } - - static findOneFailed(name: string, where: Dictionary | IPrimaryKey): ValidationError { - return new ValidationError(`${name} not found (${inspect(where)})`); - } - - static missingMetadata(entity: string): ValidationError { - return new ValidationError(`Metadata for entity ${entity} not found`); - } - static invalidPropertyName(entityName: string, invalid: string): ValidationError { return new ValidationError(`Entity '${entityName}' does not have property '${invalid}'`); } - static multipleDecorators(entityName: string, propertyName: string): ValidationError { - return new ValidationError(`Multiple property decorators used on '${entityName}.${propertyName}' property`); - } - static invalidType(type: Constructor>, value: any, mode: string): ValidationError { const valueType = Utils.getObjectType(value); @@ -175,8 +103,88 @@ export class ValidationError extends Error { return new ValidationError(`Using operators inside embeddables is not allowed, move the operator above. (property: ${className}.${propName}, payload: ${inspect(payload)})`); } - private static fromMessage(meta: EntityMetadata, prop: EntityProperty, message: string): ValidationError { - return new ValidationError(`${meta.className}.${prop.name} ${message}`); +} + +export class MetadataError extends ValidationError { + + static fromMissingPrimaryKey(meta: EntityMetadata): MetadataError { + return new MetadataError(`${meta.className} entity is missing @PrimaryKey()`); + } + + static fromWrongReference(meta: EntityMetadata, prop: EntityProperty, key: keyof EntityProperty, owner?: EntityProperty): MetadataError { + if (owner) { + return MetadataError.fromMessage(meta, prop, `has wrong '${key}' reference type: ${owner.type} instead of ${meta.className}`); + } + + return MetadataError.fromMessage(meta, prop, `has unknown '${key}' reference: ${prop.type}.${prop[key]}`); + } + + static fromWrongTypeDefinition(meta: EntityMetadata, prop: EntityProperty): MetadataError { + if (!prop.type) { + return MetadataError.fromMessage(meta, prop, `is missing type definition`); + } + + return MetadataError.fromMessage(meta, prop, `has unknown type: ${prop.type}`); + } + + static fromWrongOwnership(meta: EntityMetadata, prop: EntityProperty, key: keyof EntityProperty): MetadataError { + const type = key === 'inversedBy' ? 'owning' : 'inverse'; + const other = key === 'inversedBy' ? 'mappedBy' : 'inversedBy'; + + return new MetadataError(`Both ${meta.className}.${prop.name} and ${prop.type}.${prop[key]} are defined as ${type} sides, use '${other}' on one of them`); + } + + static entityNotFound(name: string, path: string): MetadataError { + return new MetadataError(`Entity '${name}' not found in ${path}`); + } + + static multipleVersionFields(meta: EntityMetadata, fields: string[]): MetadataError { + return new MetadataError(`Entity ${meta.className} has multiple version properties defined: '${fields.join('\', \'')}'. Only one version property is allowed per entity.`); + } + + static invalidVersionFieldType(meta: EntityMetadata): MetadataError { + const prop = meta.properties[meta.versionProperty]; + return new MetadataError(`Version property ${meta.className}.${prop.name} has unsupported type '${prop.type}'. Only 'number' and 'Date' are allowed.`); + } + + static fromUnknownEntity(className: string, source: string): MetadataError { + return new MetadataError(`Entity '${className}' was not discovered, please make sure to provide it in 'entities' array when initializing the ORM (used in ${source})`); + } + + static fromUnknownBaseEntity(meta: EntityMetadata): MetadataError { + return new MetadataError(`Entity '${meta.className}' extends unknown base entity '${meta.extends}', please make sure to provide it in 'entities' array when initializing the ORM`); + } + + static noEntityDiscovered(): MetadataError { + return new MetadataError('No entities were discovered'); + } + + static onlyAbstractEntitiesDiscovered(): MetadataError { + return new MetadataError('Only abstract entities were discovered, maybe you forgot to use @Entity() decorator?'); + } + + static duplicateEntityDiscovered(paths: string[]): MetadataError { + return new MetadataError(`Duplicate entity names are not allowed: ${paths.join(', ')}`); + } + + static multipleDecorators(entityName: string, propertyName: string): MetadataError { + return new MetadataError(`Multiple property decorators used on '${entityName}.${propertyName}' property`); + } + + static missingMetadata(entity: string): MetadataError { + return new MetadataError(`Metadata for entity ${entity} not found`); + } + + private static fromMessage(meta: EntityMetadata, prop: EntityProperty, message: string): MetadataError { + return new MetadataError(`${meta.className}.${prop.name} ${message}`); + } + +} + +export class NotFoundError extends ValidationError { + + static findOneFailed(name: string, where: Dictionary | IPrimaryKey): NotFoundError { + return new NotFoundError(`${name} not found (${inspect(where)})`); } } diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 6929fa0277fe..4d7f1e011ff0 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1,7 +1,7 @@ export * from './Configuration'; export * from './ConfigurationLoader'; -export * from './ValidationError'; export * from './Logger'; export * from './Utils'; export * from './RequestContext'; export * from './SmartQueryHelper'; +export * from './errors';