Exception Handling Guidelines

Forums and Minerals, the new Internet tools

Image via Wikipedia

Follow class naming conventions, but add Exception to the end of the name.
Some rules listed below are to be followed in Exceptions blocks or classes:

  1. Never do a “catch” exception and do nothing. If you hide an exception, you will never know if the exception happened or not.
  2. In case of exceptions, give a friendly message to the user, but log the actual error with all possible details about the error, including the time it occurred, method and class name etc.
  3. Always catch only the specific exception, not generic exception as well as system exceptions.
  4. You can have an application level (thread level) error handler where you can handle all general exceptions. In case of an ‘unexpected general error’, this error handler should catch the exception and should log the error in addition to
    giving a friendly message to the user before closing the application, or allowing the user to ‘ignore and proceed’.
  5. Do not write try-catch in all your methods. Use it only if there is a possibility that a specific exception may occur. For example, if you are writing into a file, handle only FileIOException.
  6. Do not write very large try-catch blocks. If required, write separate try-catch for each task you perform and enclose only the specific piece of code inside the try-catch. This will help you find which piece of code generated the exception and you can give specific error message to the user.
  7. You may write your own custom exception classes, if required in your application. Do not derive your custom exceptions from the base class SystemException. Instead, inherit from ApplicationException.
  8. To guarantee resources are cleaned up when an exception occurs, use a try/finally block. Close the resources in the finally clause. Using a try/finally block ensures that resources are disposed even if an exception occurs.
  9. Error messages should help the user to solve the problem. Never give error messages like “Error in Application”, “There is an error” etc. Instead give specific messages like “Failed to update database. Make sure the login id and password are correct.”
  10. When displaying error messages, in addition to telling what is wrong, the message should also tell what the user should do to solve the problem. Instead of message like “Failed to update database.” suggest what should the user do: “Failed to update database. Make sure the login id and password are correct.”
  11. Show short and friendly message to the user. But log the actual error with all possible information. This will help a lot in diagnosing problems.
  12. Define a global error handler in Global.asax to catch any exceptions that are not handled in code. You should log all exceptions in the event log to record them for tracking and later analysis.
Advertisements

Collection was modified; enumeration operation may not execute

Self-loop

Image via Wikipedia

The error occurs when you are performing a for each loop over a generic list or a collection and there is a line of code inside the loop that is trying to modify the contents of the list. Take a look at the code below :

                                        Dim myList As New List(Of Integer)
                                        myList.Add(1)
                                        myList.Add(2)
                                        myList.Add(3)
                                        myList.Add(4)
                                        myList.Add(5)
                                        For Each i As Integer In myList
                                            myList.Remove(i)
                                        Next

the above code will throw an InvalidOperationException because we are removing items from the list while we are still iterating over its items using the for each loop.

a simple fix to the above code would be replacing the for each loop with the standard index loop as follows :

                                      For i As Integer = 0 To myList.Count - 1
                                            myList.Remove(i)
                                        Next

Cross-thread operation not valid: Control ‘ControlName’ accessed from a thread other than the thread it was created on

A multithreaded process with two threads execu...

Image via Wikipedia

This is a common error when you are developing a multithreading application you often recieve an InvalidOperationException
indicating that a thread is trying to access an object that was created on another thread. A typical code block that generates this
error is shown below :

Dim th As New Threading.Thread(AddressOf test)
 

Private Sub test()
    TextBox1.Text = "using textbox from another thread"
End Sub


Private Sub Form1_Load(ByVal sender As System.Object, _ 
 ByVal e As System.EventArgs) Handles MyBase.Load
     th.Start()
End Sub

In the code above, TextBox1 is a normal textbox placed in the form. As we predicted, the error is thrown because TextBox1 belongs to main thread
, which is the single thread that runs the form and th is another thread accessing the textbox from the test function. To resolve
this problem, each control must be exclusively accessed from it belonging thread. What we are talking about here is to apply
context switching whenever we need to access controls on different threads. This is easy to do in .net framework. In face, we can
also add a small functionality to check whether a cross threading operation is required before we actually go on and swtich the context
because context switching has its performance penalties.

Using the Invoke method of the form, we can pass in a MethodInvoker object, which is a delegate specifying the address of the
function that we would like to invoke in case if an invokation is required by the form’s thread. To do the actual testing if an invokation
is needed, we use the form’s InvokeRequired property. Below is the working version of the code:

Dim th As New Threading.Thread(AddressOf test)
 

Private Sub test()
      If Me.InvokeRequired Then
             Me.Invoke(New MethodInvoker(AddressOf test))
       Else
                TextBox1.Text = "using textbox from another thread"
        End If
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, _ 
 ByVal e As System.EventArgs) Handles MyBase.Load
     th.Start()
End Sub

Swap 2 variables without using temporary variable!

Perhaps the oldest technique most of programmers use, whether beginners or professional coders, to swap 2 variables a and b, is to declare a new temporary variable c, copy a to c then assign b to a and finally assign c to b. The following code should look familiar:

        Dim a As Integer = 10
        Dim b As Integer = 20
        Dim c As Integer = a
        a = b
        b = c

This technique is really simple and easy to understand and perhaps this is the main reason of its widespread use. However, there is a minor problem using this technique, which is the allocation of a new variable(c) which incurs more memory usage. Although its just 1 more variable overhead, a total of 4 bytes integer it still represents a major drawback for memory-critical applications or on machines where memory space is too low or limited(such as mobile devices). The first new technique is also simple and has the advantage of not allocating space for a new temporary variable. This method uses addition and subtraction in a clever way in order to keep track of the a and b:

        Dim a As Integer = 10
        Dim b As Integer = 20
        a = a + b
        b = a - b
        a = a - b

Lets analyze this code line by line:

  1. a=10
  2. b=20
  3. a= 10 + 20 = 30
  4. b= 30 – 20 = 10
  5. a= 30 – 10 = 20
  6. Final result: a=20 and b=10

This is really a very nice and smart way of swapping. You can encapsulate it in a function that takes two arguments by reference so that you don’t have to remember this arithmetic steps each time but I will leave this as an exercise to the reader:). Now let’s take a look at the next method which involves multiplication and division instead of addition and subtraction:

        Dim a As Integer = 10
        Dim b As Integer = 20
        a = a * b
        b = a / b
        a = a / b

Again,Lets analyze this code line by line:

  1. a=10
  2. b=20
  3. a= 10 * 20 = 200
  4. b= 200 / 20 = 10
  5. a= 200 / 10 = 20
  6. Final result: a=20 and b=10

I have created a console application and added all the 3 methods then I surrounded each method with a very long loop in order to simulate a compute intensive operation in order to measure the speed of each one using a Stopwatch. The complete code looks like this:

    Sub Main()
        Dim a As Integer = 10
        Dim b As Integer = 20
        Console.WriteLine("Original values")
        Console.WriteLine("a: {0}, b: {1}", a, b)
        Dim s As New Stopwatch
        s.Start()
        For i As Integer = 0 To 10000002
            a = a + b
            b = a - b
            a = a - b
        Next
        s.Stop()
        Console.WriteLine("Swap using addition subtraction")
        Console.WriteLine("a: {0}, b: {1}, Time: {2}", a, b, s.ElapsedMilliseconds)

        a = 10
        b = 20

        s.Restart()
        For i As Integer = 0 To 10000002
            Dim c As Integer = a
            a = b
            b = c
        Next

        s.Stop()
        Console.WriteLine("Swap with temporary variable")
        Console.WriteLine("a: {0}, b: {1}, Time: {2}", a, b, s.ElapsedMilliseconds)

        a = 10
        b = 20

        s.Restart()
        For i As Integer = 0 To 10000002
            a = a * b
            b = a / b
            a = a / b
        Next
        s.Stop()
        Console.WriteLine("Swap using multiplication division")
        Console.WriteLine("a: {0}, b: {1}, Time: {2}", a, b, s.ElapsedMilliseconds)

        Console.ReadKey()
    End Sub

Running this application produced interesting measurements, 1 in particular that I did not expect:

As you can see, the method using a temporary variable outperformed the other two. I was expecting that the multiplication and division method to be the worst because of the division overhead but I thought that the addition and subtraction method will compete, but it looks like using the temporary variable is about twice faster. This can be explained because memory allocation in the .net framework is incredibly fast and the heap manager does some magic in allocation. In fact, memory allocation in .net is as fast as allocating memory in C using the malloc function and it’s even faster sometimes.

Final thoughts:
If you are using the temporary variable method for swapping variables, keep using it:) it’s the right thing to do unless you are a memory geek or developing applications for mobile devices then perhaps you should switch to the addition/subtraction method.