diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-02-22 13:25:28 -0500 | 
|---|---|---|
| committer | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-02-22 13:25:28 -0500 | 
| commit | 77a3dadd0b128f4421e16c3465fbf609c483241b (patch) | |
| tree | f3666b2410d27cc4b02e2fe8dff8fceea3b5497c | |
| parent | 7b1a1480dc440eb1c7b1a6170ac0964bc4c7a3fa (diff) | |
Make schema errors have more information
| -rw-r--r-- | ext/bg/js/database.js | 43 | 
1 files changed, 40 insertions, 3 deletions
| diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index a5919868..453cf15f 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -326,7 +326,8 @@ class Database {          const archive = await JSZip.loadAsync(archiveSource);          // Read and validate index -        const indexFile = archive.files['index.json']; +        const indexFileName = 'index.json'; +        const indexFile = archive.files[indexFileName];          if (!indexFile) {              throw new Error('No dictionary index found in archive');          } @@ -334,7 +335,7 @@ class Database {          const index = JSON.parse(await indexFile.async('string'));          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 version = index.format || index.version; @@ -393,7 +394,7 @@ class Database {                  if (!file) { break; }                  const entries = JSON.parse(await file.async('string')); -                JsonSchema.validate(entries, schema); +                Database._validateJsonSchema(entries, schema, fileName);                  for (let entry of entries) {                      entry = convertEntry(entry); @@ -508,6 +509,42 @@ class Database {          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) {          const termBank = (              version === 1 ? |