Monday, August 03, 2009

An interesting task

Over on the OzDotNet mailing list, one of the posts was asking if it’s possible to detect if there is an active exception. I believe the purpose is to change the behaviour of a method that is being called from a catch block.

While I suspect the what I consider to be the “best” solution is to pass a parameter into the function, the idea really hit a “geek spot” somewhere deep inside me. So, without further ado:

   1:          public static bool InCatchBlock()


   2:          {


   3:              StackTrace stackTrace = new StackTrace();


   4:   


   5:              bool inCatchBlock = false;


   6:   


   7:              foreach (StackFrame stackFrame in stackTrace.GetFrames())


   8:              {


   9:                  MethodBody body = stackFrame.GetMethod().GetMethodBody();


  10:   


  11:                  if (body != null)


  12:                  {


  13:                      foreach (ExceptionHandlingClause clause in body.ExceptionHandlingClauses)


  14:                      {


  15:                          bool isFinally = clause.Flags == ExceptionHandlingClauseOptions.Finally;


  16:   


  17:                          if (!isFinally && stackFrame.GetILOffset() >= clause.HandlerOffset && 


  18:                              stackFrame.GetILOffset() < clause.HandlerOffset + clause.HandlerLength)


  19:                          {


  20:                              inCatchBlock = true;


  21:   


  22:                              break;


  23:                          }


  24:                      }


  25:   


  26:                      if (inCatchBlock)


  27:                      {


  28:                          break;


  29:                      }


  30:                  }


  31:              }


  32:   


  33:              return inCatchBlock;


  34:          }




This function above, simply walks the current call stack and checks at each frame to see if we are inside a declared catch block. It seems to work fine for the limited testing I’ve done.



On a related note, I personally believe that code should not care about where it’s called from, as it creates intimate coupling with upstream code, which is more likely than not to create issues with your code.