Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Joi v16: TypeError issue with valid(Joi.ref(x)).error() #2147

Closed
BanovMiroslav opened this issue Sep 25, 2019 · 9 comments
Closed

Joi v16: TypeError issue with valid(Joi.ref(x)).error() #2147

BanovMiroslav opened this issue Sep 25, 2019 · 9 comments
Assignees
Labels
bug Bug or defect
Milestone

Comments

@BanovMiroslav
Copy link

Context

  • node version:10.16.3
  • joi version:16.1.4
  • environment (node, browser):node
  • used with (hapi, standalone, ...):hapi/standalone
  • any other relevant information:

What are you trying to achieve or the steps to reproduce ?

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.

Which result you had ?

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)

What did you expect ?

{
  value: {...}
  error: {...}
}
@hueniverse hueniverse self-assigned this Sep 25, 2019
@triron2018
Copy link

triron2018 commented Sep 27, 2019

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

@hueniverse hueniverse added the bug Bug or defect label Sep 29, 2019
@hueniverse hueniverse added this to the 16.1.5 milestone Sep 29, 2019
@hueniverse
Copy link
Contributor

error() requires an Error object. I fixed it so that it is better communicated now.

@BanovMiroslav
Copy link
Author

BanovMiroslav commented Oct 1, 2019

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?

@hueniverse
Copy link
Contributor

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 }

@BanovMiroslav
Copy link
Author

BanovMiroslav commented Oct 1, 2019

I think the problem is it’s Error object rather then the object that was returned before. So it can’t be Json encoded. I return this to a client via my api and I was using error() to tweak the message

@hueniverse
Copy link
Contributor

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.

@BanovMiroslav
Copy link
Author

Ok thanks. Looking forward to using this new version now that I understand why I have these regressions

@BanovMiroslav
Copy link
Author

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.

@lock
Copy link

lock bot commented Jan 9, 2020

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.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Bug or defect
Projects
None yet
Development

No branches or pull requests

3 participants