Level:
3/10 at Ellenbogen’s scale.
Preface:
You have the following code:
try
{
// Some code which can throw any kind of exception
}
catch(Exception e)
{
// If e is from DataGatewayException type – throw the original exception;
// Otherwise, wrap the exception with DataGatewayException and throw it.
// In any case – this “block” will throw only DataGatewayException.
if (!(e is DataGatewayException))
throw WrapAndPublishException(e); // *
else
throw;
}
* WrapAndPublishException method returns a new object from DataGatewayException type (which wraps the original exception).
The Challenge:
Refactor the code above so it will be more readable and extendable(in case we want to re-throw other exception types as well).
Use your imagination.
Just use the language:
try
{
// Some code which can throw any kind of exception
}
catch (DataGatewayException e) {throw e;}
catch(Exception e) { throw WrapAndPublishException(e); }
Hey Yoni.
This is not the correct answer. Think about this – do you preserve the original(!) exception stack trace while using "throw e;" ? What is wrong here ?
I must admit I didn’t know the stack trace gets altered when you re-throw an existing exception. Seems stupid, doesn’t it?
But, if you change it to ‘throw’ (which, if I had refactored correctly should have stayed the way it was) it will do the trick, right?
First, let’s get rid of the negative exclamation (which I on general rule doesn’t like, too easy to miss).
try
{
//do work
}
catch(Exception e)
{
if ((e is DataGatewayException))
throw;
else
throw WrapAndPublishException(e);
}
Better yet:
try
{
//do work
}
catch(Exception e)
{
throw WrapAndPublshException(e); // DataGateWayExceptions need to be published as well, don’t they
//The stack trace will be logged as well, so we can write it
//anyway, this assume that DataGateway get the InnerException set, so it doesn’t actually matter if we are throwing a new exception, the stack trace is still visible (and can be view in the stack trace in the Windows exception dialog or in the cosole or in the logs.
}
Yoni – that’s it. using "throw;" will do the trick, and you don’t have to catch the exception as an object (warning at compile time).
WRONG: catch (DataGatewayException e) – no usage of "e".
RIGHT: catch (DataGatewayException)
Ayende – That wasn’t what I mean, but it’s my fault that I haven’t explained it properly. (1) If I get here DataGatewayException that means that someone else should have published it aleardy(I don’t want to publish it again) and (2) I don’t want to wrap a DataGatewayException inside a DataGatewayException.