I always like reading what other developers are suggesting as “best practices”. Occasionally, I come across one that seems to defy logic, such as “don’t allow comments in your code”. Initially the statement seems bonkers, but then you read-up on the topic, you are able to find out why anybody would agree with such a statement. Usually, these practices are solid ideas, under the proper conditions.
This month, I came across another “best practice” that sounded totally bananas: “Don’t put try/catch blocks in your .net code”. I must say that my first inclination was to call names and throw rotten vegetables. The mere concept of allowing an error or flaw, to go un-recorded, well, it makes my skin crawl. I have a small box full of “hero badges” that were given to me, simply for putting error handling & logging into a project. I am not exaggerating. Error handling & logging will save the day. If you have haystacks and needles, your metal detector is called: error handling & logging. It is a big thing. So, how could you recommend to someone, “don’t use it”, and still think you are giving good advice?
I had to dig around a little to understand why anyone would think that exception handling would be a bad idea. Once I stopped thinking like me, the answers were pretty clear.
- Swallowing errors is very evil – “Golly, I can’t connect to the database right now. No worries. I’ll just ignore this dead-end and just let the program keep cranking along and hope it all works-out anyway” (is NOT something I would say). It is even worse when it gets reported as a bug, and then, the developers search for a bug, but never think to look inside of the Try block, because it isn’t reporting an error (because someone caught the error and didn’t do anything with it).
If you’ve ever made an error handler to suppress an error, I hate you!
- Showing error messages to users – Most users can’t solve the problem anyhow. So showing them information about the error is not very friendly or useful. (most of the time)
- Logic performed in an error handler is just a bad design. It indicates laziness and a lack of discipline from a developer.
- If you use a consolidated error handler (eg. ELMAH), it will not be able do its job properly if you catch and suppress an error.
- Did you think of everything? What if you missed a line or two of code with your error handlers? You think you got them all, but you did not.
- Logging errors wrong – I’ve seen systems that log the errors in a database. So what happens when the database is down? Think about it. Now please kick yourself if you’ve ever done this. If you need error handlers for your error handlers, then you might want to re-think your strategy.
Here are a few “right ways” to deal with an exception once you have caught it.
- Elmah makes stuff much easier. Start with Elmah.
- Elmah is kind-of dumb and only logs what gets into an exception. If you have some code with additional info, you may want to add a try-catch block to get the information about the current app-state (vars, params, etc), and put it into an exception. The original exception should go into the inner exception. Re-throw. Value-added!
- Whatever you are using for error handling and logging, think about what happens when the destination is not available. Hard drives can get full (if neglected) and databases go-down sometimes. If you insist on logging to a DB or web service, then you better implement an error-logger in your error-logger. (If the DB or WS is down, write it to a file). If you write it to files, and the drive gets full, log that condition to a different drive or just slap yourself for allowing it to get full and vow to grow-up and monitor your drive space better.
- And of course, be sure to test each variation of your error logger, to ensure it works.
- Set a regular cadence to monitor your error log and drive-space, if applicable
(ie. Check it every day at 10 am).
There are right-ways and wrong-ways to do good things. Error logging can be a cure or a poison, depending on how you use it. YMMV.