diff --git a/API.md b/API.md index 2a77fd2e7..dbf568c2d 100755 --- a/API.md +++ b/API.md @@ -275,15 +275,6 @@ Creates a new customized instance of the **joi** module where: Note that the original **joi** module is not modified by this. -### `isExpression(expression)` - -Checks whether or not the provided argument is an expression. - -```js -const expression = Joi.x('{a}'); -Joi.isExpression(expression); // returns true -``` - ### `in(ref, [options])` Creates a [reference](#refkey-options) that when resolved, is used as an array of values to match against the rule, where: @@ -299,6 +290,23 @@ const schema = Joi.object({ }); ``` +### `isError(err)` + +Checks whether or not the provided argument is a validation error. + +```js +Joi.isError(new Error()); // returns false +``` + +### `isExpression(expression)` + +Checks whether or not the provided argument is an expression. + +```js +const expression = Joi.x('{a}'); +Joi.isExpression(expression); // returns true +``` + ### `isRef(ref)` Checks whether or not the provided argument is a reference. Useful if you want to post-process error messages. diff --git a/lib/annotate.js b/lib/annotate.js index e96f7ad6d..42798fc3e 100755 --- a/lib/annotate.js +++ b/lib/annotate.js @@ -10,23 +10,23 @@ const internals = { }; -exports.error = function (source, stripColorCodes) { +exports.error = function (stripColorCodes) { - if (!source._original || - typeof source._original !== 'object') { + if (!this._original || + typeof this._original !== 'object') { - return source.details[0].message; + return this.details[0].message; } const redFgEscape = stripColorCodes ? '' : '\u001b[31m'; const redBgEscape = stripColorCodes ? '' : '\u001b[41m'; const endColor = stripColorCodes ? '' : '\u001b[0m'; - const obj = Clone(source._original); + const obj = Clone(this._original); - for (let i = source.details.length - 1; i >= 0; --i) { // Reverse order to process deepest child first + for (let i = this.details.length - 1; i >= 0; --i) { // Reverse order to process deepest child first const pos = i + 1; - const error = source.details[i]; + const error = this.details[i]; const path = error.path; let node = obj; for (let j = 0; ; ++j) { @@ -75,9 +75,9 @@ exports.error = function (source, stripColorCodes) { message = `${message}\n${redFgEscape}`; - for (let i = 0; i < source.details.length; ++i) { + for (let i = 0; i < this.details.length; ++i) { const pos = i + 1; - message = `${message}\n[${pos}] ${source.details[i].message}`; + message = `${message}\n[${pos}] ${this.details[i].message}`; } message = message + endColor; diff --git a/lib/errors.js b/lib/errors.js index 92a9bdf8b..0823f924f 100755 --- a/lib/errors.js +++ b/lib/errors.js @@ -1,7 +1,5 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); - const Annotate = require('./annotate'); const Common = require('./common'); const Template = require('./template'); @@ -243,9 +241,6 @@ exports.details = function (errors, options = {}) { exports.ValidationError = class extends Error { - isJoi = true; - name = 'ValidationError'; - constructor(message, details, original) { super(message); @@ -253,9 +248,15 @@ exports.ValidationError = class extends Error { this.details = details; } - annotate(stripColorCodes) { + static isError(err) { - Assert(Annotate.error, 'Error annotation is not supported'); - return Annotate.error(this, stripColorCodes); + return err instanceof exports.ValidationError; } }; + + +exports.ValidationError.prototype.isJoi = true; + +exports.ValidationError.prototype.name = 'ValidationError'; + +exports.ValidationError.prototype.annotate = Annotate.error; diff --git a/lib/index.js b/lib/index.js index 73b0c2b8b..8813f516d 100755 --- a/lib/index.js +++ b/lib/index.js @@ -183,6 +183,7 @@ internals.methods = { return joi; }, + isError: Errors.ValidationError.isError, isExpression: Template.isTemplate, isRef: Ref.isRef, isSchema: Common.isSchema, @@ -232,8 +233,7 @@ internals.assert = function (value, schema, annotate, args /* [message], [option throw message; } - annotate = annotate && typeof error.annotate === 'function'; - const display = annotate ? error.annotate() : error.message; + const display = annotate && typeof error.annotate === 'function' ? error.annotate() : error.message; if (error instanceof Errors.ValidationError === false) { error = Clone(error); diff --git a/test/errors.js b/test/errors.js index 9ffc4e05c..a9b104d6a 100755 --- a/test/errors.js +++ b/test/errors.js @@ -21,6 +21,7 @@ describe('errors', () => { const err = Joi.valid('foo').validate('bar').error; expect(err).to.be.an.error(); expect(err.isJoi).to.be.true(); + expect(Joi.isError(err)).to.be.true(); });