Couple of points about:
catch (SpecialException e) ...
The statement:
throw new ApplicationException(e.Message);
is usually not a good practice. You should instead use something like this:
throw new ApplicationException("Some context message that provides
additional meaning to the user.",e);
The original statement would work but usually is not a good practice - all
you are doing is changing the exception type, but you are losing the
original stack trace and are not providing any additional information at
all.
One justification for the original statement is if there is security
sensitive information in the original exception that you do not want exposed
to a higher level component and you wish to hide the data.
An additional reason for transforming the exception type is if the exception
that is caught (SpecialException), is a custom exception that is defined in
an assembly that is not available to modules that have called into your code
(e.g. they are calling across a boundary, either appdomain, machine, etc).
In this case you actually do need to discard the original type and replace
it with a different type. This is because if the calling module does not
have access to the assembly then it will not be able to deserialize the
exception object and that will itself cause another exception to be thrown,
masking the original exception.
In either case I would preserve the original exception message and add
additional context information to aid users in figuring out why it didn't
work.
Another point is that use of the type ApplicationException is being
discouraged as it does not really add much value. There is a ongoing debate
about this and it has not yet been resolved in any camp's favor, but I
personally never use it anymore - I either use a custom exception (rare), or
use the same exception type that was caught (i.e. clone the type), or
sometimes just use Exception.
Couple of points about
catch (Exception)
{
Rollback();
throw;
}
Again, this works, but due to a bug in the current version of the runtime it
will lose the original stack information and replace it with a stack that
begins where the throw statement occurs. This is supposed to be fixed in
Whidbey. It also does not add any context information.
I usually prefer to catch-wrap-throw rather then simply rethrow the original
exception. In this case I would probably use something like...
catch (SpecialException e)
{
Rollback();
throw new Exception("Unable to complete.",e);
}
catch(Exception ex)
{
Rollback();
throw new Exception("I fell down and can't get up.",ex);
}
I always prefer to add information in order to make life as easy as possible
for the users - cryptic error messages should be avoided at all costs.