With this post I start the series on how to handle the errors right. I’ve been thinking and experimenting with how to do it better, and I want to share this knowledge.
First of all, I want to give an example with the error handling that was done wrong, unfortunately something that happens too often:
Once upon a time I had to deal with a Point-Of-Sale application written in Java. I’d start it and it would immediately exit with an exception saying that it could not open the configuration file because it doesn’t exist. The file was there, and the kernel tracing showed that it opened the file fine, yet it still gave the error. Finally I decompiled this $%^$^ and was able to understand what happened:
It opened the configuration XML file fine but the XML contained a reference to the DTD file as an URL. Next thing it tried to open the DTD file, and since the machine was not connected to the internet, it failed to open the connection. For which it caught the network exception and thrown the exception of being unable to open the DTD file. Which it caught again and thrown another exception,now about being unable to open the XML file. This exception became the mystery. The fix was to remove the DTD clause from the XML file, and everything started working.
The lesson in this example: don’t hide the error information. If it had let the original exception propagate through, that would be more helpful (because of the stack trace) but still mysterious as to why does it try to open a connection. But if each code layer added its layer of information on top of the error message, instead of replacing it, the error would become straightforward and easy to fix: can’t open the XML file because can’t open its DTD file because there is no network connectivity.
Of course, the other lesson is that DTDs suck every which way, and specifying them in an XML file is totally wrong. The only way to use the DTDs is to override them from the source code, making the XML parser ignore whatever DTD is in the XML file and use the fixed one. Even then you can’t know if the DTD is correct or if someone had messed with it, and your program must not crash if the loaded document happens to not conform to the expected DTD. But this is really off-topic :-)