vue: Custom error message from prop validator

What problem does this feature solve?

Currently, if a custom validator fails, we get a console error log saying Invalid prop: custom validator check failed for prop 'email' which is not helpful if you’re using a third-party component. The only way to find out what failed is to jump into the source code of the component and try to understand what does this custom validator do. If the custom validator can provide a custom message that immensely changes developer experience e.g. Instead of Invalid prop: custom validator check failed for prop 'email', it can say, Invalid prop: the prop 'email' should be a valid GMail address.

What does the proposed API look like?

No change in API signature only behavior of validator function. If a validator function throws an error, use it as a custom message for prop validation. Also, allow {{name}} interpolation in error message. So the email can be defined as:

...
  props: {
    email: {
      validator(value) {
        if (!value.endsWith('@gmail.com')) throw new Error('the prop '{{name}}' should be a valid GMail address.')
        return true
     }
   }
...

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 15
  • Comments: 20 (9 by maintainers)

Most upvoted comments

The simplest way for now to print a custom error message and not produce a double error is to raise a console error (in my case I don’t want to throw an Error) and return true in the validator function. Like in this example:

selectableRows: {
      validator: value => {
        if (![undefined, true, false, 1, '1', ''].includes(value)) {
          console.error(
            'Wrong value for the `selectableRows` prop. ' +
            `Given: "${value}", expected one of: [undefined, true, false, 1, '1', ''].`
          )
        }
        return true
      }
    }

+1

When the returned value from a validator is truthy, I wonder if it would be simpler to check if what’s returned is a string, then if it is, make that the warning message. Thoughts?

The simplest way for now to print a custom error message and not produce a double error is to raise a console error (in my case I don’t want to throw an Error) and return true in the validator function. Like in this example:

selectableRows: {
      validator: value => {
        if (![undefined, true, false, 1, '1', ''].includes(value)) {
          console.error(
            'Wrong value for the `selectableRows` prop. ' +
            `Given: "${value}", expected one of: [undefined, true, false, 1, '1', ''].`
          )
        }
        return true
      }
    }

Whilst this does work, it still doesn’t feel like it should be the way to achieve this. Logging an error could be useful (in an isolated context within a custom validator) but I would guess most who are writing code that is going to production shouldn’t be adding console.error in places.

My use case for needing custom error messages is for both cross prop validation and validation on itself. I am the author of a design system and therefore I am concerned about consumers/other developers being aware of prop validation when in development. I need to avoid errors to leak to anywhere but development (Vue warn won’t do this).

I have had to create this which I am using in a props watch handler with immediate: true to be able to validate a component’s props against each other:

export function validateVueProps(propCondition, errorMessage) {
  if (propCondition && process.env.NODE_ENV !== "production") {
    throw new TypeError(`${errorMessage}`);
  }
}

My second use case is having a custom validator for prop type of Array. I want to specify a value and label key that exists in the passed Array. It would be nice to display custom message - "Your options must contain a label and value", for example. A similar thing referenced here https://github.com/vuejs/vue/issues/6496#issuecomment-922364934. e.g.

validator: (options) => options.map(key => Object.keys(key)).includes("label" && "value")

A generic [Vue warn] on quite specific validation seems antithetical.

My specific use cases (I appreciate cross prop validation is not really on topic here) shouldn’t necessarily deter from the idea that:

  • Vue supplies a way of passing in custom validators. This could determine any behaviour you like given that prop.
  • A [Vue warn] is useful insofar that it tells you something that has happened but not why. Surely only half the way there for the reason you wanted to write a custom validator in the first place? I am currently relying on writing JSDoc in the component to specify prop behaviour.
  • Relying on [Vue warn] is a good thing in that the warnHandler is turned off for "production".

Just my thoughts, thanks all.

Why not let the validator return the error message? If result is a function call the function, this allows custom logging nicely, if it returns a string use it as the message. Otherwise return the default message.