How not to write an error message

Users and programmers see error messages very differently.

When a user sees an error message, they think, “Oh, no.  Something went wrong.”  Rarely, in my experience, does the user think to read the error message, or to use it as a clue toward what might have happened.  Technology is so opaque, so hard to understand, and so seemingly random that people have stopped paying attention to error messages.  The situation hasn’t been helped by the “blue screen of death,” or messages that say, “Error -16,” or the like.  The more people get such messages, the more they’re likely to tune them out.

When clients ask me for help with a problem, I often ask them to tell me what error message they saw. This question often surprises them; they don’t expect that the error message will tell them what their next step could be. But in good software, it will.

Programmers thus see error messages as helpful hints toward how a solution can be solved. (Of course, programmers and engineers are generally interested in solving problems — something that the public at large doesn’t necessarily share.)  When I see an error message, I ask, “Hmm, let’s see if this is telling me what I can do to remove the problem.” I see the error message as a helpful hint that the system’s programmer left for me, rather than an insult or yet more proof that technology is fickle.

But it turns out that when programmers are new or inexperienced with a technology, they often exhibit the same behavior as novices. This week, I taught a two-day course in Git. Now, Git is not exactly known for being an easy-to-understand system — but as I showed my students, there are many times when the error message does tell us something useful. Perhaps it’s using sui generis Git-flavored technobabble, but once you understand how Git works behind the scenes, the message will actually make sense.

My point is that even if error messages are ignored by the majority of users, they can and should be written such that people can benefit from them. Even if the number of people who will read these messages is small, you should at least give them a hint, and indicate why things when wrong.

Indeed, a good error message should say: (1) what inputs were provided that caused this error, (2) what was wrong with those inputs, and (3) what you can do to solve the problem. It’s totally fine to log lots of additional information to a logfile or database for further analysis later on. But to the degree that it’s possible, error messages should try to help people to help themselves.

That’s nice in theory, of course, In reality, there are the completely, maddeningly, stupid error messages that give all programmers a bad name.

Case in point: About two years ago, I bought a 12-trip train ticket (“kartisiya”) from Modi’in (where I live) to Bnai Brak (where I had a client). I figured that I would make enough trips to Bnai Brak that it was worth getting these tickets, and putting them on my electronic ticket card, known in Israel as a “Rav kav.” But it turned out that it was actually faster for me to get off at one of the Tel Aviv train stations, and then walk to this client’s office.

A few days ago, I decided that if I hadn’t used these tickets in two years, I should probably get them refunded. Or changed to another city. Or something.  Unfortunately, because they were on my Rav Kav, no station would refund my money. Nor could they change the tickets to be between Modi’in and another city. I was stuck with 12 tickets to a train station that I wasn’t likely to need or use in the near future.

Fortunately, Israel Railways has a fancy Web site. I went there, and found that I could submit questions to their help line via a Web form. Note that Israel Railways has removed phone numbers and e-mail addresses from their “contact us” page; if you want to contact them, you’re encouraged to (1) use a Web form, (2) send a fax, or (3) send postal mail.

So I went to the Web form, filled in my story about my 12-trip ticket to Bnai Brak, provided lots of personal details, and was greeted with the following message:

train-fail

If you don’t read Hebrew, then here’s my quick transaction of the central text:

Form for public queries

Dear customer,

The system wasn’t able to handle your query.

Thanks for contacting us!

So, which is it? Are they thanking me?  Or telling me that something went wrong?  (Or both?) And did something go wrong because of a failure on my part, or on theirs?  Should I re-submit my query?  (I did; I got the same failure a second time.)

In the end, I discovered that there is a live-chat option on the Israel Railways site. Surprisingly enough, it was staffed by a real human, who asked me what was wrong.  I told her what I wrote above — and she said that complaint has been registered, and someone will get back to me in the near future.

I believe that they will get back to me. And I believe (hope) that I’ll be able to get my money back on those tickets.

But I keep thinking about the programmer who implemented this error message, and how he or she has, without knowing it, contributed to the general public’s sense that technology is random, unfriendly, and destined to drive us mad.

Are you a programmer? If so, do you consider the content of your error messages when you write them, and what people will do with them if and when they appear? Remember that error messages are meant to be read by people, not machines — and try to write them accordingly.

One thought on “How not to write an error message”

  1. I quite frequently practice “Error Message Driven Programming”: I know that specific omissions of my program will produce a helpful error message. For instance, if I don’t implement a function, the program will remind me with all the necessary details. With some scripting, the error message will even produce an empty function template to be copied into the program.

    Now! I purposefully just write code that uses functions — without defining them yet. I purposefully don’t create input files needed by my program. I don’t make programs executable. I just hit the ‘run the one test’ button.

    Of course, the program reminds me precisely what I need to do: “Create the file!” Ok. I create the file and put some source code there with not-yet-defined functions. “Make the file executable!”. Ok. Done. “Implement: sub Foo::bar { … }”. Ok — Let me give you a few more questions to ask me in the future.

    That way, programming is like a conversation with the program itself. It keeps me focused one thing at the time, yet ensuring that I don’t forget anything. Of course, when I leave something out on purpose I quickly think through the process to ensure that the question will be covered by the current test. That’s just a quick mental check that can be forgotten when ticked off: The program will remember; without any todo list.

    The fun part is that I start teaching my program to be nice with me: I don’t want it to ask me unrelated questions. So I don’t implement unrelated features. Just one thought a time — and the program ‘gets it’: It drills in on the details of just this one thought. Until all details are taken care of. “Ok. Test passed.”

    Here, this method links up with your blog post: I literally live off my error messages. They brighten up my day, they help me get my work done. And I see the practical value of a helpful error message. I think: What info can I add to the message to smooth out my workflow? What is superfluous? And I get an immediate feedback on my error message design decisions: “asdfgaet? Please improve that error message.”

Leave a Reply

Your email address will not be published. Required fields are marked *

÷ one = eight