What if I had something like this:
try
{
//work
}
catch (ArgumentNullException e)
{
HandleNullException();
Logger.log("ArgumentNullException " + e);
DoSomething();
}
catch (SomeOtherException e)
{
HandleSomeOtherException();
Logger.log("SomeOtherException " + e);
DoSomething();
}
catch (Exception e)
{
HandleException();
Logger.log("Exception " + e);
DoSomething();
}
Now as we can see, I'm trying to handle exceptions for some different cases. BUT whenever an exception is raised, I'm always calling the method DoSomething()
at the end. Is there a smarter way to call DoSomething()
if there is an exception? If I added a finally
block and called DoSomething()
there, it would always be called, even when there is no exception. Any suggestions?
Java Catch Multiple Exceptions A try block can be followed by one or more catch blocks. Each catch block must contain a different exception handler. So, if you have to perform different tasks at the occurrence of different exceptions, use java multi-catch block.
No, multiple catch blocks cannot be executed. Once first catch block is catched, it will not read the next block.
Yes, we can define one try block with multiple catch blocks in Java. Every try should and must be associated with at least one catch block.
You cannot have multiple try blocks with a single catch block. Each try block must be followed by catch or finally.
If I added a
finally
block and calledDoSomething()
there, it would always be called, even when there is no exception.
What you are looking for is known in the CLI standard (partition IIA, chapter 18) as a fault handler. Although .NET implements them, the C# language does not directly support them. However, they can be emulated:
bool success = false;
try
{
…
success = true;
}
catch (…)
{
…
}
…
finally
{
if (!success)
{
DoSomething();
}
}
Note that there is no need to set the flag inside every catch
handler, as some answers here suggest. Simply negate the test, and you only need to set the flag once, at the end of the try
block.
You can use the following code which actually does remove redundancies.
try
{
//work
}
catch (Exception e)
{
Handle(e);
}
Where the Handle
method is:
static void Handle(Exception e)
{
var exceptionType = e.GetType();
//Use an if/else block, or use a Dictionary<Type, Action>
//to operate on your exception
Logger.log(exceptionType + " " + e);
DoSomething();
}
What you are doing now is about as good as it gets.
If you need to call this function whenever an exception happens, but not otherwise, and you must have different code for handling different exceptions, than this is the best that can be done.
Why not just:
try
{
//work
}
catch (Exception e)
{
if (e is ArgumentNullException)
HandleNullException();
else if (e is SomeOtherException)
HandleSomeOtherException();
else
HandleException();
Logger.log(e.GetType().Name + " " + e);
DoSomething();
}
The type name logged will be the actual runtime type, so for example "IndexOutOfRangeException"
may be logged instead of just "Exception"
if you're in case three, but I see this as an improvement over what you have now.
Edit: Above code looks awful with the if
–else if
logic checking on types. If we introduced polymorphism, it could be more beautiful:
try
{
//work
}
catch (HandleableException e)
{
e.Handle(); // this calls a **virtual** method, each override does what's relevant
Logger.log(e.GetType().Name + " " + e);
DoSomething();
}
Of course, if some of the Exception
classes in question cannot be modified by us, it would be impossible to give them a Handle()
method. The .Handle()
could also be an extension method (instead of a virtual
instance method), but then the type checking (ugly code) would have to be done inside that method. Then this becomes quite similar to Eve's answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With