Skip to content

Commit

Permalink
Add support for verbose Ajv option (#1718)
Browse files Browse the repository at this point in the history
  • Loading branch information
cesumilo authored and lehni committed Mar 3, 2024
1 parent 3673fcd commit aa59a8e
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 6 deletions.
20 changes: 14 additions & 6 deletions lib/model/AjvValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class AjvValidator extends Validator {
}

validator.call(model, json);
const error = parseValidationError(validator.errors, modelClass, options);
const error = parseValidationError(validator.errors, modelClass, options, this.ajvOptions);

if (error) {
throw error;
Expand Down Expand Up @@ -143,7 +143,7 @@ class AjvValidator extends Validator {
}
}

function parseValidationError(errors, modelClass, options) {
function parseValidationError(errors, modelClass, options, ajvOptions) {
if (!errors) {
return null;
}
Expand Down Expand Up @@ -178,13 +178,21 @@ function parseValidationError(errors, modelClass, options) {
// More than one error can occur for the same key in Ajv, merge them in the array:
const array = errorHash[key] || (errorHash[key] = []);

// Use unshift instead of push so that the last error ends up at [0],
// preserving previous behavior where only the last error was stored.
array.unshift({
// Prepare error object
const errorObj = {
message: error.message,
keyword: error.keyword,
params: error.params,
});
};

// Add data if verbose enabled
if (ajvOptions.verbose) {
errorObj.data = error.data;
}

// Use unshift instead of push so that the last error ends up at [0],
// preserving previous behavior where only the last error was stored.
array.unshift(errorObj);

++numErrors;
}
Expand Down
75 changes: 75 additions & 0 deletions tests/integration/misc/#1718.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const _ = require('lodash');
const expect = require('expect.js');
const { Model } = require('../../../');
const { AjvValidator } = require('../../../lib/model/AjvValidator');
const { ValidationError } = require('../../../lib/model/ValidationError');

module.exports = (session) => {
describe('When Ajv verbose is enabled, pass through the data field in exception #1718', () => {
class A extends Model {
static get tableName() {
return 'a';
}

static createValidator() {
return new AjvValidator({
onCreateAjv: (ajv) => {
// Here you can modify the `Ajv` instance.
},
options: {
allErrors: true,
validateSchema: false,
ownProperties: true,
v5: true,
verbose: true,
},
});
}

static get jsonSchema() {
return {
type: 'object',
required: ['id'],
properties: {
id: { type: 'integer' },
},
};
}
}

beforeEach(() => {
return session.knex.schema
.dropTableIfExists('a')
.createTable('a', (table) => {
table.integer('id').primary();
})
.then(() => {
return Promise.all([session.knex('a').insert({ id: 1 })]);
});
});

afterEach(() => {
return session.knex.schema.dropTableIfExists('a');
});

it('the test', () => {
return A.query(session.knex)
.insert({ id: '2' })
.catch((err) => {
expect(err).to.be.an(ValidationError);
expect(err.data).to.be.an('object');
expect(err.data.id).to.be.an('array');
expect(err.data).to.eql({
id: [
{
message: 'must be integer',
keyword: 'type',
params: { type: 'integer' },
data: '2',
},
],
});
});
});
});
};

0 comments on commit aa59a8e

Please sign in to comment.