Throwing Exceptions

by alski 10. September 2006 22:55

I came across this article on Exception Throwing by Krysztof Cwalina, and I didn't think its all very good advice. Admittedly I didn't write a highly recommended book, but heres my take on it.

Before I start to look at the points, I want to clarify what an Exception is for. Heres a C# example.

string yourName = title + " " + forename + " " + surname;

This code will work > 99.999% of the time. It requires a combination of operating conditions, timing and CLR implementation in order that it generates an OutOfMemoryException. You can of course force those conditions with a simple loop.

List bigList = new List();
while(true)
{
   string yourName =
title + " " + forename + " " + surname;
   bigList.Add(yourName);
}

In the first example the Exception occurs when it is not expected. With the loop then the exception is expected but we dont know when. It is an unusual occurrence. In both of these cases, we have come across a circumstance where we cannot expect to continue processing in the normal manner.

Right lets look at Krysztof's points.

  • Consider terminating the process by calling System.Environment.FailFast (.NET Framework 2.0 feature) instead of throwing an exception, if your code encounters a situation where it is unsafe for further execution.

First, as a library developer you should NEVER call this method. As a library you run as a client of an application. This method prevents the application from any attempts at soft failure, it prevents the application from performing any exception logging. If you look at the MSDN information, it describes the use of FailFast to replace Application.Exit().

Now consider this code

static void main()
{
   try
   {
      Application.ThreadException += new ThreadExceptionEventHandler(PublishException);//Assume PublishException() performs same code as catch handler
      Application.Run(new Form1());
   }
   catch (Exception ex)//Catches only unhandled exceptions in the application
   {
      ExceptionManager.Publish(ex);
   }
}

The use of FailFast will prevent the Exception from being reported in either case. (More information on ThreadExceptionEventHandler). How many times did we all see the VS2005Beta dialog asking if we want to send an error to MS? That functionality can only be implemented if the underlying libraries let us cleanup, and I want to offer my client applications the chance to do that.

  • Consider performance implications of throwing exceptions.
There is virtually no RELEASE time performance implication for throwing exceptions. Krisztof goes on to say this, but I think the original point is misleading. John Skeet has a great article on Exception throwing performance. If you are worried about throwing exceptions then read John's article. Still dont believe it, then try it for yourself.
  • Consider using exception builder methods.
I agree with this, but I do wish Krysztof had made one point clearer, he is effectively suggesting the use of a Factory method that is the calling code to promote reuse. Usually Exceptions are defined with three constructors, (see below). However you can always define others, and what is a Constructor if not a Factory method on the object?

public XXXException();
public XXXException(string message);
public XXXException(string message, System.Exception innerException);

If you can then try to use the constructor approach as it provides your code for reuse everywhere that the exception is provided, if not then consider the local Factory methods on the caller.

  • Do not throw exceptions from exception filter blocks. When an exception filter raises an exception, the exception is caught by the CLR, and the filter returns false. This behavior is indistinguishable from the filter executing and returning false explicitly and is therefore very difficult to debug.
I believe Krisztof's point comes from this FxCop page. First, what is an exception filter? I thought I understood most terminology but this is a new one to me. The first hit on Google points to this MSDN magazine Q&A: .Net matters: Const in C#, Exception Filters and IWin32Window and more, which gets additional 'clarification' as an editors note.

C# does not include support for exception filters. [Editor's Update - 3/21/2004: This answer concerns user filters, the kind of filter generally implied by the term "exception filter". C# does not support user filters. As shown in the example, it does support type filters.]

But several google results later we find Keith Brown's post on Exception Filters considered dangerous.

...in the context of an exception filter (e.g., the Where clause in VB).

So an exception filter is a VB.Net specific syntax [catch ...where Filter()] than can possibly be used to call code insecurely. I think I'll stay clear.
However I would still envisage that there is no problem in throwing exceptions in Exception type filters, but here I would always recommend creating the new Exception with a constructor that takes the lower level exception. This provides a neat pattern where the new exception is enough for the application to determine what to do with the exception, but the InnerException provides details for why it happened, if you need log this or debug your error handling.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Comments

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

RecentComments

Comment RSS