Make schema errors have more information

This commit is contained in:
toasted-nutbread 2020-02-22 13:25:28 -05:00
parent 7b1a1480dc
commit 77a3dadd0b

View File

@ -326,7 +326,8 @@ class Database {
const archive = await JSZip.loadAsync(archiveSource); const archive = await JSZip.loadAsync(archiveSource);
// Read and validate index // Read and validate index
const indexFile = archive.files['index.json']; const indexFileName = 'index.json';
const indexFile = archive.files[indexFileName];
if (!indexFile) { if (!indexFile) {
throw new Error('No dictionary index found in archive'); throw new Error('No dictionary index found in archive');
} }
@ -334,7 +335,7 @@ class Database {
const index = JSON.parse(await indexFile.async('string')); const index = JSON.parse(await indexFile.async('string'));
const indexSchema = await this._getSchema('/bg/data/dictionary-index-schema.json'); const indexSchema = await this._getSchema('/bg/data/dictionary-index-schema.json');
JsonSchema.validate(index, indexSchema); Database._validateJsonSchema(index, indexSchema, indexFileName);
const dictionaryTitle = index.title; const dictionaryTitle = index.title;
const version = index.format || index.version; const version = index.format || index.version;
@ -393,7 +394,7 @@ class Database {
if (!file) { break; } if (!file) { break; }
const entries = JSON.parse(await file.async('string')); const entries = JSON.parse(await file.async('string'));
JsonSchema.validate(entries, schema); Database._validateJsonSchema(entries, schema, fileName);
for (let entry of entries) { for (let entry of entries) {
entry = convertEntry(entry); entry = convertEntry(entry);
@ -508,6 +509,42 @@ class Database {
return schemaPromise; return schemaPromise;
} }
static _validateJsonSchema(value, schema, fileName) {
try {
JsonSchema.validate(value, schema);
} catch (e) {
throw Database._formatSchemaError(e, fileName);
}
}
static _formatSchemaError(e, fileName) {
const valuePathString = Database._getSchemaErrorPathString(e.info.valuePath, 'dictionary');
const schemaPathString = Database._getSchemaErrorPathString(e.info.schemaPath, 'schema');
const e2 = new Error(`Dictionary has invalid data in '${fileName}' for value '${valuePathString}', validated against '${schemaPathString}': ${e.message}`);
e2.data = e;
return e2;
}
static _getSchemaErrorPathString(infoList, base='') {
let result = base;
for (const [part] of infoList) {
switch (typeof part) {
case 'string':
if (result.length > 0) {
result += '.';
}
result += part;
break;
case 'number':
result += `[${part}]`;
break;
}
}
return result;
}
static _getDataBankSchemaPaths(version) { static _getDataBankSchemaPaths(version) {
const termBank = ( const termBank = (
version === 1 ? version === 1 ?