Sometimes, when people besides myself program, there are problems in an application. Okay, I’m being a little facetious. Sometimes, even when I program, there will be errors during the lifetime of an application. This is to be expected if you are a developer. We know that nothing is perfect. We know that there are all different types of hardware problems we couldn’t account for. People don’t use our programs like we thought they would, and end-users don’t know how their software works under the hood. If one click didn’t work, try two. Try clicking harder. Try closing the program while it’s doing important work. They try everything.
This is why it is necessary to have useful error messages when the program encounters a problem, whether it be bad data, an odd code path, or misuse on the part of the user. (And it needs to handle it properly.)
Useful error messages like this one:
No? Not useful you say? But it tells us that Josh caused the problem! We can always contact Josh, right? All right, maybe that’s acceptable (Note: It’s not.) while you’re actively developing. But how annoying it is when this is actually in your middleware. WHO THE HECK IS JOSH!? WHAT ACTUALLY WENT WRONG!? (Why are there OK and Cancel buttons?) Besides, Josh is out-the-door in a few months and you just don’t know it. He got an offer from Blizzard and wants to work on the next Diablo game.
When providing an error message, more is more. There is a lot of useful information you can and usually should provide.
- For Developers: A Stack Trace. There is a reason most languages provide these with exceptions, so don’t toss them out! At least write them to a log file and tell me where to get them.
- For Developers: A relevant error message. I worked with a certain API and when I catch an error from their mystical DoWork function I get a superb error message: “ERROR.” How descriptive! This happens for every different error that gets returned from the pump. It is informative and I completely appreciate it. I know exactly what line of code is incorrect and what API functions I am calling in the wrong manner. I am also being as sarcastic as text allows. Use helpful error messages and describe possible problems / solutions in them. At least tell me that X was NULL.
- For Users: Educate them. Let users know what they may have done incorrectly in order to produce the error message. They don’t care that X was NULL or that you accessed an array out of bounds in MainClass::MainFunction() at line 67. They just don’t want to get that error anymore. You want to educate and guide them in that direction. (But you need to fix / prevent that error.)
- For Users: Error codes do not suffice. Error codes are an additional resource, they are not the sole resource. As cool as it is to copy and paste (You CAN copy and paste your error message, correct?) an error code into Google and discovering myriads of pages wondering what it is and how to fix it, it is also cool to see what the error is directly on screen. The error code should be used to help label, not to replace an informative description.
For example, a simple way to handle it would be:
void DescriptiveErrorFunction(int errorCode, const char* internalMessage, const char* publicMessage)
char errorString[ 15 ];
sprintf(errorString, "Error %d", errorCode);
MessageBox(NULL, publicMessage, errorString, MB_OK|MB_ICONEXCLAMATION);
#elseif defined(INTERNAL_RELEASE) || defined(DEBUG)
MessageBox(NULL, internalMessage, errorString, MB_OK|MB_ICONEXCLAMATION);
You could get really in depth with it if you wanted to by logging the internal message to a file, sending data to a server, creating pre-defined error messages that come pre-filled out. The code is the limit.
So get out there and make everything awesome!