Category name´╝ÜExceptions

Correct generic exception handling (catch(Exception){ … })

A very nice comment tail is growing at the post “Why catch(Exception)/empty is bad” on the CLR team blog. I tend to agree but there are perfectly valid reason’s to do a generic catch but with a correct handler, an empty handler is *always* bad. For example to cleanup some resources that you have allocated or logging some state that could be helpful in reproducing this specific error condition. What my number one rule is regarding generic catches is that they always need to re-throw the catched exception.

void MyMethod(int myCoolNumber){
   try{
      // Doing cool stuff with my cool number!
   }
   catch(Exception ex){
      // We could log about this condition and add the argument value.
      throw;
   }
}

If I see code that has a generic catch but doesn’t re-throw it or that wraps it then the code will be immediately corrected or be marked for refactoring.

Possible corrections:

  • specifying a specific Exception type(s) or
  • adding the throw keyword or
  • removing the wrapped exception after the throw or
  • removing the creation of a new exception without an inner exception

COM Exceptions and the ErrorCode property

Today I fixed a nasty bug in one of our applications. The first version had something like the following code construction:

 

   Type t = Type.GetTypeFromProgID(“My.ComComponent”, serverName);
   var component = (ComThingie)Activator.CreateInstance(t);
   SubItem item = component.Indexer[itemName]

The application was throwing an COMException here that was catched in a general COMException like:

   SubItem item;
   try{ item = component.Indexer[itemName]; } catch(COMException cex) { item = null; }

But this would catch *all* COM exceptions so I altered it to the following code:

   SubItem item = null;
   try{
      item = component.Indexer[itemName];
   }catch(COMException cex) {
      if(cex.ErrorCode != 0x8002000B) throw; //DISP_E_BADINDEX
   }

Code compiles fine but at runtime this fails and the question was why on earth is this failing? Turns out that the ErrorCode property is of type int and not uint that I expected. What happens now is that the negative value of ErrorCode is now compared with the positive value 0x8002000B. I needed to convert the value 0x8002000B to the int value -2147352565.

   const int DISP_E_BADINDEX = -2147352565;
   SubItem item = null;
   try{
      item = component.Indexer[itemName];
   }catch(COMException cex) {
      if(cex.ErrorCode != DISP_E_BADINDEX ) throw; //DISP_E_BADINDEX
   }

Now the exception handling is working as expected.

Hope this helps a couple of souls ­čśë

  • Recent Posts
  • Recent Comments
  • Archives
  • Categories
  • Meta