When my array schema includes more than one possible value, error message will be quite general and there is no way to make it more accurate.
example code:
const Joi = require('joi');
const schema = Joi.array()
.items(Joi.object({
type: 'text',
messages: Joi.array().items(Joi.string().max(2048)).min(1).max(30).required()
}))
.items(Joi.object({
type: 'image',
imageUrl: Joi.string().uri().required()
}));
const value = {
type: 'text',
messages: []
};
console.log(Joi.validate([value], schema));
Error: "value" at position 0 does not match any of the allowed types
Error: "value" at position 0 fails because [child "messages" fails because ["messages" must contain at least 1 items]]
Happy to take a PR if you ever manage to find a strategy to determine which is the better choice between all provided schemas.
With this feature: https://github.com/hapijs/joi/issues/1325 this issue can be closed. To more accurate error messages, just simply use when extensively.
For example:
const Joi = require('joi');
const fooType = Joi.object()
.keys({
type: 'foo',
foo: Joi.string().valid('foo')
});
const barType = Joi.object()
.keys({
type: 'bar',
bar: Joi.string().valid('bar')
});
const item = Joi.object()
.when(Joi.object({ type: 'foo' }).unknown(), { then: fooType })
.when(Joi.object({ type: 'bar' }).unknown(), { then: barType });
const schema = Joi.array().items(item);
const value = {
type: 'foo',
bar: 'bar'
};
schema.validate([value], err => console.log(err && err.message));
will result in:
Error: "value" at position 0 fails because ["bar" is not allowed]
Thanks @Marsup !
Cool, thanks for letting me know.
const Joi = require('joi');
const fooType = Joi.object().keys({
type: 'foo',
foo: Joi.string().valid('foo')
});
const barType = Joi.object().keys({
type: 'bar',
bar: Joi.string().valid('bar')
});
const item = Joi.object()
.when(Joi.object({ type: 'foo' }).unknown(), { then: fooType })
.when(Joi.object({ type: 'bar' }).unknown(), { then: barType });
const schema = Joi.array().items(item);
schema.validate([{ type: 'bad type' }], (err) => console.log(err && err.message));
The code approve will not fail, as long as enter a type not defined in the item schema.
Is there simple way to guard against that ?
I found a solution perhaps not so pretty but it works
const item = Joi.object({ type: Joi.string().valid('foo', 'bar') })
.when(Joi.object({ type: 'foo' }).unknown(), { then: fooType })
.when(Joi.object({ type: 'bar' }).unknown(), { then: barType });
@kaareal your solution is the way I'm doing it too, just get used to it ;)
That's because Joi.object({ type: 'foo' }) is strictly equivalent to Joi.object({ type: Joi.only('foo') }), notice how type is not required.
Most helpful comment
With this feature: https://github.com/hapijs/joi/issues/1325 this issue can be closed. To more accurate error messages, just simply use
whenextensively.For example:
will result in:
Thanks @Marsup !