Trying to validate two fields, making sure they are the same. Use case: password + re_password fields. This worked on Joi v15 but doesn't appear to work with Joi v16.
const schema = Joi.object().keys({
key_first: Joi.string().required(),
key_second: Joi.string().required().valid(Joi.ref('key_first')).error(() => 'key_second must match key_first'),
})
schema.validate({
key_first: 'something',
key_second: 'something else',
}, {abortEarly: false})
Seems to work if I remove the error() call. The problem is item.path is undefined, and it throws an exception.
Debug: internal, implementation, error
TypeError: Cannot read property 'filter' of undefined
at Object.exports.details (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/errors.js:227:29)
at Object.exports.process (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/errors.js:177:52)
at Object.internals.entry (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/validator.js:139:26)
at Object.exports.entry (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/validator.js:25:30)
at internals.Base.validate (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/base.js:531:26)
at handler (/home/miroslav/Projects/joitest/server.js:18:12)
at module.exports.internals.Manager.execute (/home/miroslav/Projects/joitest/node_modules/@hapi/hapi/lib/toolkit.js:41:33)
at Object.internals.handler (/home/miroslav/Projects/joitest/node_modules/@hapi/hapi/lib/handler.js:46:48)
at exports.execute (/home/miroslav/Projects/joitest/node_modules/@hapi/hapi/lib/handler.js:31:36)
at Request._lifecycle (/home/miroslav/Projects/joitest/node_modules/@hapi/hapi/lib/request.js:312:68)
Debug: internal, implementation, error
TypeError: Cannot read property 'filter' of undefined
at Object.exports.details (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/errors.js:227:29)
at Object.exports.process (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/errors.js:177:52)
at Object.internals.entry (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/validator.js:139:26)
at Object.exports.entry (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/validator.js:25:30)
at internals.Base.validate (/home/miroslav/Projects/joitest/node_modules/@hapi/joi/lib/base.js:531:26)
at handler (/home/miroslav/Projects/joitest/server.js:18:12)
at module.exports.internals.Manager.execute (/home/miroslav/Projects/joitest/node_modules/@hapi/hapi/lib/toolkit.js:41:33)
at Object.internals.handler (/home/miroslav/Projects/joitest/node_modules/@hapi/hapi/lib/handler.js:46:48)
at exports.execute (/home/miroslav/Projects/joitest/node_modules/@hapi/hapi/lib/handler.js:31:36)
at Request._lifecycle (/home/miroslav/Projects/joitest/node_modules/@hapi/hapi/lib/request.js:312:68)
{
value: {...}
error: {...}
}
const schema = Joi.object().keys({
key_first: Joi.string().required(),
key_second: Joi.string().required().valid(Joi.ref('key_first'))**_.error(new Error( 'key_second must match key_first'))_**,
})
schema.validate({
key_first: 'something',
key_second: 'something else',
}, {abortEarly: false})
===> when using Error Instance - Joi NOT returning any errors
error() requires an Error object. I fixed it so that it is better communicated now.
There's a related problem that error doesn't return any error, period. If I change the above example to:
.error(() => new Error('key_second must match key_first'))
Then there's no error.
Same with: .error(new Error('key_second must match key_first'))
@hueniverse What do you think? Should we reopen this or create new issue?
Seems to work fine for me:
> const Joi = require('.');
> const schema = Joi.object().keys({
... key_first: Joi.string().required(),
... key_second: Joi.string().required().valid(Joi.ref('key_first')).error(new Error( 'key_second must match key_first')),
... })
> schema.validate({
... key_first: 'something',
... key_second: 'something else',
... }, {abortEarly: false})
{ value: { key_first: 'something', key_second: 'something else' },
error:
Error: key_second must match key_first
at repl:3:81
at Script.runInThisContext (vm.js:122:20)
at REPLServer.defaultEval (repl.js:332:29)
at bound (domain.js:402:14)
at REPLServer.runBound [as eval] (domain.js:415:12)
at REPLServer.onLine (repl.js:642:10)
at REPLServer.emit (events.js:203:15)
at REPLServer.EventEmitter.emit (domain.js:448:20)
at REPLServer.Interface._onLine (readline.js:308:10)
at REPLServer.Interface._line (readline.js:656:8) }
And
> const Joi = require('.');
> const schema = Joi.object().keys({
... key_first: Joi.string().required(),
... key_second: Joi.string().required().valid(Joi.ref('key_first')).error(()=>new Error( 'key_second must match key_first')),
... })
> schema.validate({
... key_first: 'something',
... key_second: 'something else',
... }, {abortEarly: false})
{ value: { key_first: 'something', key_second: 'something else' },
error:
Error: key_second must match key_first
at Object.Joi.object.keys.key_second.Joi.string.required.valid.error (repl:3:85)
at Object.internals.finalize (/home/eran/code/hapijs/joi/lib/validator.js:460:36)
at Object.exports.validate (/home/eran/code/hapijs/joi/lib/validator.js:335:26)
at internals.Base.$_validate (/home/eran/code/hapijs/joi/lib/base.js:747:26)
at Object.validate (/home/eran/code/hapijs/joi/lib/types/keys.js:107:45)
at Object.exports.validate (/home/eran/code/hapijs/joi/lib/validator.js:313:26)
at Object.internals.entry (/home/eran/code/hapijs/joi/lib/validator.js:131:28)
at Object.exports.entry (/home/eran/code/hapijs/joi/lib/validator.js:25:30)
at internals.Base.validate (/home/eran/code/hapijs/joi/lib/base.js:531:26)
at repl:1:8 }
I think the problem is it鈥檚 Error object rather then the object that was returned before. So it can鈥檛 be Json encoded. I return this to a client via my api and I was using error() to tweak the message
Well, you are using it wrong.
If you want to override the message, you should use .message(), .messages(), or .prefs({ messages }).
.error() is specifically designed to override the joi error and return the exact object you are providing.
Ok thanks. Looking forward to using this new version now that I understand why I have these regressions
message() didn't work because any.valid doesn't support rules.
messages() worked:
Joi.string().required().valid(Joi.ref('key_first')).messages({'any.only': 'key_second must match key_first'})
Docs are a bit sketchy on those.
This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.
Most helpful comment
Well, you are using it wrong.
If you want to override the message, you should use
.message(),.messages(), or.prefs({ messages })..error()is specifically designed to override the joi error and return the exact object you are providing.