loading...

How do you support detailed validation error messages?

crenshaw_dev profile image Michael Crenshaw ・2 min read

I was irked by this Tweet from Sebastian McKenzie:

If you’re writing validation code, please never make it output “Incorrect foo” or “Invaid bar”. Pleeeaaase just tell me what I need to fix, and why it’s invalid.

It irked me not because Sebastian is wrong... on the contrary, it hits too close to home. I need to implement more detailed validation messages for some of Crutchfield's inputs, but it's not clear how I should do it.

For example, take this email validation regex:

^[-a-zA-Z0-9+.*!#$\/=_]+@((([a-zA-Z0-9][-a-zA-Z0-9]{0,61}[a-zA-Z0-9])|([a-zA-Z0-9]))\.)+(([a-zA-Z0-9][-a-zA-Z0-9]{0,61}[a-zA-Z0-9])|([a-zA-Z0-9]))$
Enter fullscreen mode Exit fullscreen mode

(I know it's not great to validate email with regex - but it works for 99.999% of real-world email addresses, and it helps users catch common typos.)

A number of things can cause an address to fail validation, but the regex only communicates two states: valid or invalid.

So how do I communicate to the user what invalidated the input? I could imagine designing a series of validations using parts of the above pattern:

    [
        {
            "pattern": "^[-a-zA-Z0-9+.*!#$\/=_]",
            "message": "Your email must start with a letter, number, or one of these symbols: - + . * ! # $ \/ = _"
        },
        {
            "pattern": "@",
            "message": "Your email address must contain @"
        }
    ]
Enter fullscreen mode Exit fullscreen mode

But there are a couple problems:

  1. There's code duplication, complicating maintenance.
  2. Applying the validation requires JavaScript (the pattern attribute won't suffice).
  3. It becomes less clear for developers what is the "true" validation (which should also be used server-side) and what is just used for helpful messaging.

Here is a potential solution:

  1. Call the additional patterns "typo checks" instead of "validation," making clear they're only used to help resolve simple typos, not provide a complete validity check.
  2. Don't treat input as invalid if only the typo check fails. If the main validation pattern matches, treat the input as valid; if it doesn't match, check the other patterns to find a "friendly message."

At least that's my current plan of attack.

Does that make sense? How does your site/app handle this?

Discussion

pic
Editor guide
Collapse
twwilliams profile image
Tommy Williams

When we have troublesome inputs, we tend to put instructions near them describing the requirements, and then just let validation handle the valid/invalid states.

Sometimes we have multiple validators, to check that a field has content at all, that it isn't too long, and that it meets the required formatting checks.

But trying to encode instructions inside the validators for all the things they check for seems like the effort:reward ratio is out of whack. It also seems like it would make a nasty little maintenance headache, too, as requirements change or users find new ways to generate errors.

Collapse
marius profile image
Marius Espejo

you should checkout “yup” or “joi” which allows you to define a schema for your form objects as well as providing a custom error message.

bonus tip: if you use react for your client checkout formik for form state management which has built-in support for validating with yup schemas

Collapse
crenshaw_dev profile image
Michael Crenshaw Author

The name alone has me sold. Thanks for the tip!