Scenario
I have a method that does database operation (let's say). If during that operation any exception is raised, I just want to throw that exception to the caller. I don't want to do any specific task in the catch block, assuming caller will do whatever it wants to do with that exception. In this scenario, which one is appropriate exception handling technique?
try
{
// Some work that may generate exception
}
catch(Exception)
{
throw;
}
finally
{
// Some final work
}
Is the above equivalent to the following try/catch/finally?
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
Is the above equivalent to the following try/finally?
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
Which one is better than the other? Which one should be used?
The Try-Catch method prevents program crashes when an internal error occurs in computer programming. It is useful to prevent system errors and let the smooth flow of code execution occur. However, unlike other programming languages, VBA does not have the Try-Catch block.
In 'try-catch' the codes to handle the exceptions and what exception to be handled, that are easily readable. In 'if-else', we have one else block corresponding to one if block. Or we need to define another condition with command 'else if'. In 'try-catch' we don't have to define each 'try' block with a 'catch' block.
'e' is just a variable. ('e' stands for exception, but you can rename it anything you like, however, the data type has to remain 'Exception') The 'e' variable stores an exception-type object in this case.
From what I've read myself, the throws should be used when the caller has broken their end of the contract (passed object) and the try-catch should be used when an exception takes place during an operation that is being carried out inside the method.
No, they are not equivalent. They may be equivalent in some cases, but the general answer is no.
catch
blockscatch
block with a specified exception typeThe following will only catch managed exceptions that inherit from System.Exception
and then executes the finally
block, which will happen regardless of whether an exception was thrown or not.
try
{
// Some work that may generate exception
}
catch (Exception)
{
throw;
}
finally
{
// Some final work
}
catch
block without a specified exception typeThe following catch
block without a type specifier will also catch non-managed exceptions that are not necessarily represented by a managed System.Exception
object, and then executes the finally
block, which will happen regardless of whether an exception was thrown or not.
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
finally
block without a catch
blockIf you do not have a catch
block at all, your finally
will still be executed regardless of whether or not an exception occoured.
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
In case your catch
block doesn't specify an exception and only contains the throw;
statement, the last two are indeed equivalent. In case you don't care about non-managed exceptions and your catch
block only contains the throw;
statement, all three can be considered equivalent.
throw
The following two pieces of code contain a subtle difference. The latter will re-throw the exception, meaning that it will rewrite the exception's stack trace, so these are definitely not equivalent:
catch (Exception e)
{
throw;
}
And
catch (Exception e)
{
throw e;
}
In case you use finally
with an IDisposable
, the following two pieces of code are almost equivalent, but with some subtle differences:
using
statement won't give you a NullReferenceException
When using the try
-finally
technique, the variable remains in scope, although it is very discouraged to use any object after it has been disposed. However you can still reassign the variable to something else.
Something obj = null; try { obj = new Something() // Do something } finally { obj.Dispose(); }
And
using (var obj = new Something())
{
// Do something
}
You have some good answers so far, but there is an interesting difference that they did not mention so far. Consider:
try { ImpersonateAdmin(); DoWork(); }
finally { RevertImpersonation(); }
vs
try { ImpersonateAdmin(); DoWork(); }
catch { RevertImpersonation(); throw; }
finally { RevertImpersonation(); }
Suppose DoWork throws.
Now the first question at hand is "is there a catch block that can handle this exception", because if the answer is "no" then the behaviour of the program is implementation-defined. The runtime might choose to terminate the process immediately, it might choose to run the finally blocks before it terminates the process, it might choose to start a debugger broken at the point of the unhandled exception, it might choose to do anything it likes. Programs with unhandled exceptions are permitted to do anything.
So the runtime starts looking for a catch block. There's none in this try statement, so it looks up the call stack. Suppose it finds one with an exception filter. It needs to know if the filter will permit the exception to be handled, so the filter runs before impersonation is reverted. If the filter accidentally or deliberately does something that only an admin can do, it will succeed! This might not be what you want.
In the second example, the catch catches the exception immediately, reverts the impersonation, throws, and now the runtime starts looking for a catch block to handle the re-throw. Now if there is a filter it runs after the impersonation is reverted. (And of course the finally then reverts again; I assume that reverting impersonation is idempotent here.)
This is an important difference between these two code snippets. If it is absolutely positively forbidden for any code to see the global state that was messed up by the try and cleaned up by the finally, then you have to catch before finally. "Finally" does not mean "immediately", it means "eventually".
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