From 09b8b2de5457df65e4494b43361006c6bf01101c Mon Sep 17 00:00:00 2001 From: Adler Faulkner Date: Fri, 3 Nov 2023 13:15:02 -0700 Subject: [PATCH] feat(validations): more verbose validation error messages --- package-lock.json | 4 ++-- package.json | 2 +- src/SklEngine.ts | 45 ++++++++++++++++++++++++++++++++++++---- test/deploy/package.json | 2 +- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2444e0f..fc024e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@comake/skl-js-engine", - "version": "0.16.2", + "version": "0.16.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@comake/skl-js-engine", - "version": "0.16.2", + "version": "0.16.3", "license": "BSD-4-Clause", "dependencies": { "@comake/openapi-operation-executor": "^0.11.1", diff --git a/package.json b/package.json index 604111a..a92fbc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@comake/skl-js-engine", - "version": "0.16.2", + "version": "0.16.3", "description": "Standard Knowledge Language Javascript Engine", "keywords": [ "skl", diff --git a/src/SklEngine.ts b/src/SklEngine.ts index 44c653a..5f0dc06 100644 --- a/src/SklEngine.ts +++ b/src/SklEngine.ts @@ -171,7 +171,10 @@ export class SKLEngine { }; const report = await this.convertToQuadsAndValidateAgainstShape(entitiesOfType, nounSchemaWithTarget); if (!report.conforms) { - throw new Error(`An entity does not conform to the ${currentNoun['@id']} schema.`); + this.throwValidationReportError( + report, + `An entity does not conform to the ${currentNoun['@id']} schema.`, + ); } } } @@ -225,7 +228,10 @@ export class SKLEngine { }; const report = await this.convertToQuadsAndValidateAgainstShape(entity, nounSchemaWithTarget); if (!report.conforms) { - throw new Error(`Entity ${entity['@id']} does not conform to the ${currentNoun['@id']} schema.`); + this.throwValidationReportError( + report, + `Entity ${entity['@id']} does not conform to the ${currentNoun['@id']} schema.`, + ); } } } @@ -281,7 +287,10 @@ export class SKLEngine { const attributesWithId = { ...attributes, '@id': id }; const report = await this.convertToQuadsAndValidateAgainstShape(attributesWithId, nounSchemaWithTarget); if (!report.conforms) { - throw new Error(`Entity ${id} does not conform to the ${currentNoun['@id']} schema.`); + this.throwValidationReportError( + report, + `Entity ${id} does not conform to the ${currentNoun['@id']} schema.`, + ); } } } @@ -835,7 +844,10 @@ export class SKLEngine { const parametersSchema = verb[SKL.parameters] as NodeObject; const report = await this.convertToQuadsAndValidateAgainstShape(verbParamsAsJsonLd, parametersSchema); if (!report.conforms) { - throw new Error(`${getValueIfDefined(verb[RDFS.label])} parameters do not conform to the schema`); + this.throwValidationReportError( + report, + `${getValueIfDefined(verb[RDFS.label])} parameters do not conform to the schema`, + ); } } @@ -1076,4 +1088,29 @@ export class SKLEngine { // TODO add support for remote sources throw new Error(`Failed to get data from source ${source}`); } + + private throwValidationReportError(report: ValidationReport, errorMessage: string): void { + const reportMessages = this.validationReportToMessages(report); + throw new Error( + `${errorMessage}\n\n${reportMessages.join('\n')}`, + ); + } + + private validationReportToMessages(report: ValidationReport): string[] { + const reportMessages = []; + for (const result of report.results) { + const pathValue = result.path?.value; + if (result.message.length === 0) { + const message = `${pathValue}: Invalid due to ${result.sourceConstraintComponent?.value}`; + reportMessages.push(message); + } else { + const resultMessages = result.message + .map((message): string => `${message.value}`) + .join(', '); + const message = `${pathValue}: ${resultMessages}`; + reportMessages.push(message); + } + } + return reportMessages; + } } diff --git a/test/deploy/package.json b/test/deploy/package.json index 05bdb4d..3749f55 100644 --- a/test/deploy/package.json +++ b/test/deploy/package.json @@ -7,7 +7,7 @@ }, "main": "./dist/index.js", "dependencies": { - "@comake/skl-js-engine": "file:./comake-skl-js-engine-0.16.2.tgz", + "@comake/skl-js-engine": "file:./comake-skl-js-engine-0.16.3.tgz", "jsonld": "^6.0.0" }, "devDependencies": {