Error Messages

Error messages should be cryptic. Now that I’ve piqued your interest with the age old trick of a controversial headline I can tell you something less controversial but hopefully much more useful. I’ve always had a nagging doubt about the subject of error messages in relation to what should be presented to the user. The standard line is that you should present the user with an error message that contains information which is useful to them. They should be able to use that information to either solve the problem or, as a last resort, contact support and have them sort it out. That doesn’t seem right to me. Here’s my idea:

Only show error messages to users if you have no idea what just happened.

To continue this line of reasoning, if you have no idea what just happened, then you have no idea of the solution. Hence all you can do is report the state of the program at failure and any debug logging you may have generated. That’s not going to help the user to solve the problem. Therefore, the content of the error message should be aimed at support or, more likely, a developer. All the user needs is a message along the lines of ‘Something unexpected and probably bad happened. I’ve been unable to fix it. Please forward the attached information to support@acmeinc.com for further assistance.’ The real error message should contain things like a log file, stack trace, memory and register dump, file and line where failure happened etc. What the user sees is just a wrapper.

As a response to those conditions, what I’ve suggested is nothing very radical. This is probably the way you deal with this situation already. The interesting things are in the flip side of the maxim above. In other words if you have some idea of what is happening then you shouldn’t generate an error message. The code should treat this as a normal part of execution. You’ve anticipated the program state and execution flow so therefore you don’t have an error condition. You’ve just deviated from the default execution path. No biggie.

Don’t approach this type of situation as an error. Approach it as part of normal planned execution. What happens when you do this is that the follow up tends to be much better integrated into the user experience. A lot of times the code itself can auto-fix the problem; sometimes even silently (but be careful about surprising the user). Sometimes the user can be prompted to change something and continue. Regardless of the detailed action that needs to be taken, the whole process of interacting with the software becomes more fluid and natural as the code and design treats these anticipated problems as part of the whole design. Entering an illegal character in a POP3 password shouldn’t make the user feel like he’s generated an error in the software.

Reserve the ‘error message’ mindset for when things go unexpectedly pear shaped. And what I’m saying here is pretty much only things that you forgot to take into account. Almost all other problems can be dealt with in a controlled and sensible way. If it’s out of memory issues, then free some memory somehow or re-start the program or the machine. If it’s a disk that goes missing for some reason, then present the user with alternate storage options or shutdown the software. If the network has died then look for alternate connectivity or talk the user through some diagnostics. All these things can be anticipated and appropriate actions taken. That action might simply be to let the user know that the network has gone and that the software is shutting down. The point is that these are anticipated and dealt with as part of the normal flow of execution. In theory, there is no need to involve support as the software itself is operating correctly and can talk the user through finding a solution. Whether you’ve had the time to implement code to fully handle all these anticipatable events is another matter…

When you come across something truly unexpected, such as a violation of a routine’s preconditions or a runtime exception for example, then there’s clearly a need to involve support. The code is broken and needs fixing. Since the program is now in an unknown state, the only thing that’s usually safe and worthwhile is a shutdown or possibly a re-start. All you can present to the user is a ‘please send support this info’ type message. The program state, log, memory dump etc is useless to the user but vital to support. There are no alternatives here. No solutions or prompts to the user or workarounds. It’s game over and you want a simple, reliable catch-all strategy for when your day has gone this bad. This is the time to turn on your ‘error message’ mentality and dump all the baggage of elegance and user experience.