This weapon, or weak spot if you prefer, is almost always an issue in some way. Let us check the rhyme and then go into the specifics:
“The unexpected and unwanted, make sure you address Or one day they´ll make you some unhandled mess Some general safety net should be in place To handle the unhandled surprises with grace”
So, what does it mean?
Unexpected, and unwanted, input and/or behaviour needs to be handled gracefully.
I am not in any way saying the system should be bulletproof, or that you should have custom error messages for every single possible scenario. But a user should not be able to cause the system to break into pieces by whatever shenanigans they come up with.
Depending on your application, your level of risk acceptance, your business and your users – you can do it in a multitude of different ways.
Of course, code should have proper error handling in place. Catching exceptions before they cause any big issues and letting the user know something went wrong. If it’s something we can identify as a potential unwanted scenario we should also let the user know what they did wrong so they can fix it. (But not too helpful, since this can be exploited by hackers!)
It’s a fine balance between generalising, throwing a bunch of similar things into the same bucket and produce a generic error message, and being explicit, making sure scenarios have uniquely identifiable error messages. A good rule of thumbs for me has been that if a specific problem occurs in production, we make it explicit.
So, where to put it? You have the aspect of user friendliness, where you want the error message to show up as soon as possible and as close to the culprit as possible. Meaning as soon as a user leaves a field, it is validated and the user is immediately informed of the problem. Or, you validate the fields when the user does some sort of confirmation action – Submit a form, save, move to next screen etc. Or, you can validate in each service (or similar, depending on tech stack). Or, you can validate in the database (if you have one). Or, on any combination of those. And the further “down the stack” you get, that error needs to be sent back up towards the user in some way in order for them to know something went wrong. Which to choose? Well. No one size fits all I’m afraid. But I can at least give some pointers.
So, you want validations on your backend as well. Here you might want to both check that the data is “clean” (as in, nothing that we don’t want here) and apply business rules. Maybe we want to check for duplicates, calculate some fields or check that this user is eligible for the thing they are trying to do. But you probably don’t want to run all of those checks every time a user leaves a field, since that would be slow and cause unnecessary network traffic.
And you probably want validations on your database as well. Either by constraints on fields and formats or by different database rules. But these are even slower, and we will have to transport the error message a long way back to the user. These errors are also often the least understandable to a user.
Once upon a time we implemented a new digital form to replace a paper form. We spent a lot of time making it easy to use, understandable and tried to simplify what we could. We created guides, added pictures and put restraints in to make sure the users would always know what was expected of them.
We tested it thoroughly, especially the fields that had a minimum and maximum length, since I knew this was something that could be implemented in many ways, with different weaknesses. I entered manually, copy-pasted, copy-pasted and added, copy-pasted and added and deleted and added. Well, you get the picture. All was well!
In production we started getting really weird errors from some users. It looked ok and we just could not figure it out. First ones were just written of as “something weird with that one”, but they kept coming! Not a lot, but more than a few.
It turned out if you copy-pasted from a certain text document-program, you got some extra, invisible, characters. Since we had the validation on the frontend – this slipped by into the backend where it went kablooie.
Quote of the day
“The best error message is the one that never shows up”