Managing Exceptions in .Net

[NOTE:  This was originally posted at DevAuthority.com on 10/28/05.]

Houston We Have A Problem
Ok, we’ve all seen the .Net error pages that pop up in the browser just full of helpful information in debugging your application. Although useful (at times) to the developer, there is nothing more terrifying to an end user than filling out a form, clicking the submit button, and being presented with a Stack Trace. As developers, we need to be sure that these annoyances never reach the user. To achieve this we must implement good exception handling in our code. Just because an exception is thrown doesn’t mean that it must be fatal to the execution of our application.
In the .Net Framework an exception is actually represented as an object that inherits from the Exception Class. This object oriented approach allows us to interface with exceptions so that we can make intelligent decisions in our code.

Try and Try again!
The mechanism that VB.Net provides us for handling exceptions within our code is the “Try/Catch/Finally” construct.

Private Sub LoadUserInformationFile()
    Try
        Dim sr As StreamReader = File.OpenText("userFile.txt")
    Catch ex As Exception
        LogException(ex, ExceptionLog.Database) 
    Finally
        'Code Placed Here will run every time this code block
        'is executed regardless of error.
    End Try
End Sub

When we execute the code above, any error that we have opening the file will be turned into an Exception. This exception object will then be available to us in the Catch block. We can add code at this point to make decisions about continued code execution, give a friendly message to the user letting them know that there was a problem, and log the issue for further investigation. In the example above we are taking the exception object and passing it off to another method (LogException) that has been designed specifically for logging the pertinent information to our chosen repository. In the example above we used the Catch block to handle any exception thrown by the app in a generic fashion. We can also use multiple Catch blocks to handle specific exceptions.

Private Function DivideMyNumber() As Int16
    Try
        Dim x As Int16 = 10
        Dim y As Int16 = 0
        Return x / y
    Catch exByZero As DivideByZeroException
        'This was a divide by zero
        'We are just going to return 0 from the function.
        Return 0
    Catch ex As Exception
        LogException(ex, ExceptionLog.Database)
    End Try
End Function

In this example, we have written a function that does simple division and returns the result to the calling code. We have included two catch blocks in our function to handle errors. The first only handles DivideByZeroException objects. Whenever this type of exception is thrown it is available here and any code contained in this catch block will be executed. The second is the generic Exception type. It handles all other exceptions thrown by the system. In this case our business rules dictate that if we try to divide by zero, we just want to return zero, but in all other cases we just need to log the error for further analysis.

Exception Management Best Practices
Handle exceptions where it makes sense. When an exception is thrown, it is “bubbled” up the stack until one of two things happens, it is either handled or it reaches the end of the stack and the application terminates. We want to avoid the latter from happening, but we also may not want to handle exceptions on every line of code or every method individually. It’s up to the developer to use their best judgment, but as a rule of thumb I suggest handling specific exceptions which require specific outcomes, such as our DivideByZero example above, where they occur. You can then handle all the generic exceptions in the outermost method. When using multiple catch blocks, always order them from most specific to least specific.Although using multiple catch blocks to catch specific exception types gives us the ability to intelligently make decisions within our code, we should avoid using these constructs to control flow within our applications. Your business objects should contain the validations and rules. Don’t rely on exception handling for the enforcement of business rules.Use Finally blocks to clean up, close, or deallocate resources.The key to effective exception management is common sense. Don’t wrap all your code in Try blocks, but be certain that no unhandled errors reach the user. Your code will be easier to maintain and the user will be much happier when they don’t see those ugly errors!

 

Print | posted @ Friday, November 09, 2007 5:34 AM

Comments have been closed on this topic.