Drop from a specific exception catch to a more generic exception when the first throws and error
Say you have a method that can throw a couple different exceptions. If it throws a "LoggableException" then I want to handle it by trying to log the error in a certain place. For all other exceptions, I just want to do actions a,b,c. The code would look something like this:
try
{
CanThrowException();
}
catch ( LoggableException le )
{
Log(le.ToString());
}
catch (Exception exp)
{
a();
b();
c();
}
Now, assume that the method "Log(string s)" can also throw an exception. If it does, then we want to do the same actions, a, b, and c that we did in the generic exception. The way it is now, we have to duplicate the code in the generic exception:
try
{
CanThrowException();
}
catch ( LoggableException le )
{
try
{
Log(le.ToString());
}
catch (Exception exp)
{
a();
b();
c();
}
}
catch (Exception exp)
{
a();
b();
c();
}
What I wish we could do is let the exception thrown from "Log" to be caught in the "catch(Exception exp)" block. This could not be done by default as it would change the meaning of code that is already written, so we would have to specify whether or not a catch that has an exception of its own should drop down to another catch in the same block or not. The following is just one idea of how this could be written:
try
{
CanThrowException();
}
catch ( LoggableException le ) : drops // specifies that we stay in this block of catches and look for an Exception type that matches our new exception
{
Log(le.ToString());
}
catch (Exception exp) : dropto // specifies that this catch block can receive exceptions from previous catch blocks that threw exceptions
{
a();
b();
c();
}
4 comments
-
David
commented
Yeah, OK--that works. Thanks :)
-
Ian William James Halliday commented
You can already do this by nesting the LoggableException catch handler inside the try with its own try and adding a rethrow statement. @thzinc has the right idea but I think the following is a little more clear:
try
{
try
{
CanThrowException();
}
catch (LoggableExeption le)
{
Log(le.ToString());
throw;
}
}
catch (Exception)
{
a();
b();
c();
} -
thzinc
commented
Why not try something like the following?
try
{
CanThrowException();
}
catch (Exception exp)
{
try
{
if (exp is LoggableException)
{
Log((exp as LoggableException).ToString());
}
else
{
throw exp;
}
}
catch (Exception innerexp)
{
a();
b();
c();
}
} -
JMCF125 commented
Can't you alredy do that?