Code and software quality by advanced exception handling in .NET

3/13/2009

I'm crazy about exception handling. Not because I like when an exception occurs in the live environment, but because handling them in a proper way can help us to find defects in our system. I have an own exception handling-related process, which helps me to garantee better code quality and - of course - software quality. I'm a .NET developer, so I have .NET examples in C#, but this technique can be adopted to JAVA if you want. This is the first place time I publish it, I kept it in secret till now, so I'm very excited, I hope you feel the same :)

You probably use some cool logging framework or component to persist errors somewhere. In the .NET World most people use Log4Net, Microsoft Enterprise Library Logging Application Block or Common.Logging. These are very useful tools, all of them are easy-to-use, flexible and excellent software.

I don't want to compare these tools, you probably have preferred one. I want to point out that using these logging components isn't enough in enterprise application development.


I assume you follow all exception handling principle:


  • you don't write empty catch blocks

  • you don't throw unnecessary exceptions

  • you don't reset the call stack by rethrowing the same exception after a catch

  • you free up resources in the finally block or you use the using statement
...
The rest of the basics can be found in these articles:
[MSDN] - Best Practices for Handling Exceptions
[CodeProject] - Exception Handling Best Practices in .NET
[Howard Gilbert (Yale University)] - Exception Handling in Java and C#

All the techniques are essential above, but all of us can make mistakes, so we can't be sure that our software handles exceptions correctly.

How to implement error logging functionality in .NET with quality code?

Review your code!

I usualy make a code review after each SCRUM sprint by looking for catch blocks in the code. Quite easy work, I just press CTRL-SHIFT-F in Visual Studio and look for the "catch" keyword. I analyze the code to check if it conforms to the standards.

Sometimes we concentrate to a functionality and not to the error handling. No problem, here I'm, I will do code review. I recommend you to add this task to the checklist of your each iteration, or assign this work to somebody in the team.

How can you be sure, that your code handles each exception in a correct way?

Check your code coverage report, find uncovered catch block and add test cases to cover them. I'm not competent in determining magic numbers, how much percent are enaugh for test coverage, I check only what is not covered. I'm looking for "catch" blocks here as well. If I find some, I immediately write unit tests.

I prefer writing more unit tests related to exceptions, here you can take advantage of the ExpectedException attribute of NUnit or your favourite unit testing framework.

Using this practice you can assert:
  • if you have the correct, descriptive error message, which will help you to find mistake after reading the error log

  • if you have user-friendly error message, which doesn't contain technical details


I use TDD, so after producing red/green bars and refactoring the code, I usually call my methods with bad parameters/invalid data. All TDD professional tell this, you can find it in any TDD or unit testing book, but developers sometimes concentrate only to write assertions to check the behavioral expected by the user story/functional requirement.

Recoverable and unrecoverable exceptions are not the same


If you can recover the state of your object while catching the exception in your method, handle the exception and log it if it is necessary. But if you find that you can't recover, consider deleting your try/catch block and let your caller to handle the exception. In most cases, you -should- have exception handling at your application/service boundary, so the detailed error descriptions can't get to the client or user interface. So if you are developing a code, which isn't located at the application/component boundary, catch the exception only if you can do any useful with it.

How to make sure of your logging code does not make errors in your application?


Your logging-related code must be bullet-proof.

If your logging mechanism fails, the original error and the arisen error must be written to some other location.
If you get a failure during the logging, you must avoid throwing exception to your application.

My last advice can be utilized in the deployment phase of the development life cycle.
After installing to the production server, generate an error in your application (rename a necessary file or stop a service) to make sure your live environment logs the errors.

I have some tricks for centralized exception handling/logging, so keep checking the updates of CodeRecycling ...

0 comments: