Joi: Custom error for each validation option?

Created on 2 Mar 2019  路  5Comments  路  Source: sideway/joi

I have Joi schema and want to specify a custom error message for each of the options.

Example of my schema:

const schema = Joi.object().keys({
    name: Joi.string()
      .min(5).error(() => 'first message')
      .max(25).error(() => 'second message')
      .required().error(() => 'third message')
})

At the moment this validation works in such way: if whatever of the option is invalid only third message appears.

Expected behavior - error message appears according to which option is invalid (as default Joi behavior, but with my custom error message).

Thanks in regards!

support

Most helpful comment

@WesTyler, thanks for the explanation!

For my situation I just found such solution:

const schema = Joi.object().keys({
    title: Joi.string()
      .min(minLength)
      .max(maxLength)
      .required()
      .error((errors) => {
        return errors.map(error => {
          switch (error.type) {
            case "string.min":
              return { message: "first msg" };
            case "string.max":
              return { message: "second msg" };
            case "any.empty":
              return { message: "third msg" };
          }
        }
        )
      })

Seems not the best one, as it cause too many code, especialy if you have big form, hovewer it works as I desire.

If they're not a more convenient solution for my case, an issue can be closed.

Thanks again for your help!

All 5 comments

This is because you are not applying a custom error to each individual option, you are applying 3 sequential errors to the same single property. The following is the same end result as your code, but makes the calls more clear:

Joi.string()
      .min(5)
      .max(25)
      .required()
      .error(() => 'first message')
      .error(() => 'second message')
      .error(() => 'third message')

One option you can leverage is the callback function in .error():

Joi.string()
  .min(5)
  .max(25)
  .required()
  .error((errors) => {
    // if abortEarly === false,
    // errors contains the details for all options that failed
    // if abortEarly === true,
    // errors contains the details for the first option that failed
  })

@WesTyler, thanks for the explanation!

For my situation I just found such solution:

const schema = Joi.object().keys({
    title: Joi.string()
      .min(minLength)
      .max(maxLength)
      .required()
      .error((errors) => {
        return errors.map(error => {
          switch (error.type) {
            case "string.min":
              return { message: "first msg" };
            case "string.max":
              return { message: "second msg" };
            case "any.empty":
              return { message: "third msg" };
          }
        }
        )
      })

Seems not the best one, as it cause too many code, especialy if you have big form, hovewer it works as I desire.

If they're not a more convenient solution for my case, an issue can be closed.

Thanks again for your help!

I think that's going to be your best bet for what you're trying to do.

Glad it worked!

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.

Was this page helpful?
0 / 5 - 0 ratings