Is a finally block without a catch block a java anti-pattern? - c#

I just had a pretty painful troubleshooting experience in troubleshooting some code that looked like this:
try {
doSomeStuff()
doMore()
} finally {
doSomeOtherStuff()
}
The problem was difficult to troubleshoot because doSomeStuff() threw an exception, which in turn caused doSomeOtherStuff() to also throw an exception. The second exception (thrown by the finally block) was thrown up to my code, but it did not have a handle on the first exception (thrown from doSomeStuff()), which was the real root-cause of the problem.
If the code had said this instead, the problem would have been readily apparent:
try {
doSomeStuff()
doMore()
} catch (Exception e) {
log.error(e);
} finally {
doSomeOtherStuff()
}
So, my question is this:
Is a finally block used without any catch block a well-known java anti-pattern? (It certainly seems to be a not-readily-apparent subclass of the obviously well-known anti-pattern "Don't gobble exceptions!")

In general, no, this is not an anti-pattern. The point of finally blocks is to make sure stuff gets cleaned up whether an exception is thrown or not. The whole point of exception handling is that, if you can't deal with it, you let it bubble up to someone who can, through the relatively clean out-of-band signaling exception handling provides. If you need to make sure stuff gets cleaned up if an exception is thrown, but can't properly handle the exception in the current scope, then this is exactly the correct thing to do. You just might want to be a little more careful about making sure your finally block doesn't throw.

I think the real "anti-pattern" here is doing something in a finally block that can throw, not not having a catch.

Not at all.
What's wrong is the code inside the finally.
Remember that finally will always get executed, and is just risky ( as you have just witnessed ) to put something that may throw an exception there.

There is absolutely nothing wrong a try with a finally and no catch. Consider the following:
InputStream in = null;
try {
in = new FileInputStream("file.txt");
// Do something that causes an IOException to be thrown
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// Nothing we can do.
}
}
}
If an exception is thrown and this code doesn't know how to deal with it then the exception should bubble up the call stack to the caller. In this case we still want to clean up the stream so I think it makes perfect sense to have a try block without a catch.

I think it's far from being an anti-pattern and is something I do very frequently when it's critical do deallocate resources obtained during the method execution.
One thing I do when dealing with file handles (for writing) is flushing the stream before closing it using the IOUtils.closeQuietly method, which doesn't throw exceptions:
OutputStream os = null;
OutputStreamWriter wos = null;
try {
os = new FileOutputStream(...);
wos = new OutputStreamWriter(os);
// Lots of code
wos.flush();
os.flush();
finally {
IOUtils.closeQuietly(wos);
IOUtils.closeQuietly(os);
}
I like doing it that way for the following reasons:
It's not completely safe to ignore an exception when closing a file - if there are bytes that were not written to the file yet, then the file may not be in the state the caller would expect;
So, if an exception is raised during the flush() method, it will be propagated to the caller but I still will make sure all the files are closed. The method IOUtils.closeQuietly(...) is less verbose then the corresponding try ... catch ... ignore me block;
If using multiple output streams the order for the flush() method is important. The streams that were created by passing other streams as constructors should be flushed first. The same thing is valid for the close() method, but the flush() is more clear in my opinion.

I'd say a try block without a catch block is an anti-pattern. Saying "Don't have a finally without a catch" is a subset of "Don't have a try without a catch".

I use try/finally in the following form :
try{
Connection connection = ConnectionManager.openConnection();
try{
//work with the connection;
}finally{
if(connection != null){
connection.close();
}
}
}catch(ConnectionException connectionException){
//handle connection exception;
}
I prefer this to the try/catch/finally (+ nested try/catch in the finally).
I think that it is more concise and I don't duplicate the catch(Exception).

try {
doSomeStuff()
doMore()
} catch (Exception e) {
log.error(e);
} finally {
doSomeOtherStuff()
}
Don't do that either... you just hid more bugs (well not exactly hid them... but made it harder to deal with them. When you catch Exception you are also catching any sort of RuntimeException (like NullPointer and ArrayIndexOutOfBounds).
In general, catch the exceptions you have to catch (checked exceptions) and deal with the others at testing time. RuntimeExceptions are designed to be used for programmer errors - and programmer errors are things that should not happen in a properly debugged program.

In my opinion, it's more the case that finally with a catch indicate some kind of problem. The resource idiom is very simple:
acquire
try {
use
} finally {
release
}
In Java you can have an exception from pretty much anywhere. Often the acquire throws a checked exception, the sensible way to handle that is to put a catch around the how lot. Don't try some hideous null checking.
If you were going to be really anal you should note that there are implied priorities among exceptions. For instance ThreadDeath should clobber all, whether it comes from acquire/use/release. Handling these priorities correctly is unsightly.
Therefore, abstract your resource handling away with the Execute Around idiom.

Try/Finally is a way to properly free resources. The code in the finally block should NEVER throw since it should only act on resources or state that was acquired PRIOR to entry into the try block.
As an aside, I think log4J is almost an anti-pattern.
IF YOU WANT TO INSPECT A RUNNING PROGRAM USE A PROPER INSPECTION TOOL (i.e. a debugger, IDE, or in an extreme sense a byte code weaver but DO NOT PUT LOGGING STATEMENTS IN EVERY FEW LINES!).
In the two examples you present the first one looks correct. The second one includes the logger code and introduces a bug. In the second example you suppress an exception if one is thrown by the first two statements (i.e. you catch it and log it but do not rethrow. This is something I find very common in log4j usage and is a real problem of application design. Basically with your change you make the program fail in an way that would be very hard for the system to handle since you basically march onward as if you never had an exception (sorta like VB basic on error resume next construct).

try-finally may help you to reduce copy-paste code in case a method has multiple return statements. Consider the following example (Android Java):
boolean doSomethingIfTableNotEmpty(SQLiteDatabase db) {
Cursor cursor = db.rawQuery("SELECT * FROM table", null);
if (cursor != null) {
try {
if (cursor.getCount() == 0) {
return false;
}
} finally {
// this will get executed even if return was executed above
cursor.close();
}
}
// database had rows, so do something...
return true;
}
If there was no finally clause, you might have to write cursor.close() twice: just before return false and also after the surrounding if clause.

I think that try with no catch is anti-pattern. Using try/catch to handle exceptional conditions (file IO errors, socket timeout, etc) is not an anti-pattern.
If you're using try/finally for cleanup, consider a using block instead.

Related

What is the purpose of using the following try-catch block? c# [duplicate]

I'm looking at the article C# - Data Transfer Object on serializable DTOs.
The article includes this piece of code:
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
catch(Exception ex) {
throw ex;
}
}
The rest of the article looks sane and reasonable (to a noob), but that try-catch-throw throws a WtfException... Isn't this exactly equivalent to not handling exceptions at all?
Ergo:
public static string SerializeDTO(DTO dto) {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
Or am I missing something fundamental about error handling in C#? It's pretty much the same as Java (minus checked exceptions), isn't it? ... That is, they both refined C++.
The Stack Overflow question The difference between re-throwing parameter-less catch and not doing anything? seems to support my contention that try-catch-throw is-a no-op.
EDIT:
Just to summarise for anyone who finds this thread in future...
DO NOT
try {
// Do stuff that might throw an exception
}
catch (Exception e) {
throw e; // This destroys the strack trace information!
}
The stack trace information can be crucial to identifying the root cause of the problem!
DO
try {
// Do stuff that might throw an exception
}
catch (SqlException e) {
// Log it
if (e.ErrorCode != NO_ROW_ERROR) { // filter out NoDataFound.
// Do special cleanup, like maybe closing the "dirty" database connection.
throw; // This preserves the stack trace
}
}
catch (IOException e) {
// Log it
throw;
}
catch (Exception e) {
// Log it
throw new DAOException("Excrement occurred", e); // wrapped & chained exceptions (just like java).
}
finally {
// Normal clean goes here (like closing open files).
}
Catch the more specific exceptions before the less specific ones (just like Java).
References:
MSDN - Exception Handling
MSDN - try-catch (C# Reference)
First, the way that the code in the article does it is evil. throw ex will reset the call stack in the exception to the point where this throw statement is losing the information about where the exception actually was created.
Second, if you just catch and re-throw like that, I see no added value. The code example above would be just as good (or, given the throw ex bit, even better) without the try-catch.
However, there are cases where you might want to catch and rethrow an exception. Logging could be one of them:
try
{
// code that may throw exceptions
}
catch(Exception ex)
{
// add error logging here
throw;
}
Don't do this,
try
{
...
}
catch(Exception ex)
{
throw ex;
}
You'll lose the stack trace information...
Either do,
try { ... }
catch { throw; }
OR
try { ... }
catch (Exception ex)
{
throw new Exception("My Custom Error Message", ex);
}
One of the reason you might want to rethrow is if you're handling different exceptions, for
e.g.
try
{
...
}
catch(SQLException sex)
{
//Do Custom Logging
//Don't throw exception - swallow it here
}
catch(OtherException oex)
{
//Do something else
throw new WrappedException("Other Exception occured");
}
catch
{
System.Diagnostics.Debug.WriteLine("Eeep! an error, not to worry, will be handled higher up the call stack");
throw; //Chuck everything else back up the stack
}
C# (before C# 6) doesn't support CIL "filtered exceptions", which VB does, so in C# 1-5 one reason for re-throwing an exception is that you don't have enough information at the time of catch() to determine whether you wanted to actually catch the exception.
For example, in VB you can do
Try
..
Catch Ex As MyException When Ex.ErrorCode = 123
..
End Try
...which would not handle MyExceptions with different ErrorCode values. In C# prior to v6, you would have to catch and re-throw the MyException if the ErrorCode was not 123:
try
{
...
}
catch(MyException ex)
{
if (ex.ErrorCode != 123) throw;
...
}
Since C# 6.0 you can filter just like with VB:
try
{
// Do stuff
}
catch (Exception e) when (e.ErrorCode == 123456) // filter
{
// Handle, other exceptions will be left alone and bubble up
}
My main reason for having code like:
try
{
//Some code
}
catch (Exception e)
{
throw;
}
is so I can have a breakpoint in the catch, that has an instantiated exception object. I do this a lot while developing/debugging. Of course, the compiler gives me a warning on all the unused e's, and ideally they should be removed before a release build.
They are nice during debugging though.
A valid reason for rethrowing exceptions can be that you want to add information to the exception, or perhaps wrap the original exception in one of your own making:
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
catch(Exception ex) {
string message =
String.Format("Something went wrong serializing DTO {0}", DTO);
throw new MyLibraryException(message, ex);
}
}
Isn't this exactly equivalent to not
handling exceptions at all?
Not exactly, it isn't the same. It resets the exception's stacktrace.
Though I agree that this probably is a mistake, and thus an example of bad code.
You don't want to throw ex - as this will lose the call stack. See Exception Handling (MSDN).
And yes, the try...catch is doing nothing useful (apart from lose the call stack - so it's actually worse - unless for some reason you didn't want to expose this information).
This can be useful when your programming functions for a library or dll.
This rethrow structure can be used to purposefully reset the call stack so that instead of seeing the exception thrown from an individual function inside the function, you get the exception from the function itself.
I think this is just used so that the thrown exceptions are cleaner and don't go into the "roots" of the library.
A point that people haven't mentioned is that while .NET languages don't really make a proper distinction, the question of whether one should take action when an exception occurs, and whether one will resolve it, are actually distinct questions. There are many cases where one should take action based upon exceptions one has no hope of resolving, and there are some cases where all that is necessary to "resolve" an exception is to unwind the stack to a certain point--no further action required.
Because of the common wisdom that one should only "catch" things one can "handle", a lot of code which should take action when exceptions occur, doesn't. For example, a lot of code will acquire a lock, put the guarded object "temporarily" into a state which violates its invariants, then put it object into a legitimate state, and then release the lock back before anyone else can see the object. If an exception occurs while the object is in a dangerously-invalid state, common practice is to release the lock with the object still in that state. A much better pattern would be to have an exception that occurs while the object is in a "dangerous" condition expressly invalidate the lock so any future attempt to acquire it will immediately fail. Consistent use of such a pattern would greatly improve the safety of so-called "Pokemon" exception handling, which IMHO gets a bad reputation primarily because of code which allows exceptions to percolate up without taking appropriate action first.
In most .NET languages, the only way for code to take action based upon an exception is to catch it (even though it knows it's not going to resolve the exception), perform the action in question and then re-throw). Another possible approach if code doesn't care about what exception is thrown is to use an ok flag with a try/finally block; set the ok flag to false before the block, and to true before the block exits, and before any return that's within the block. Then, within finally, assume that if ok isn't set, an exception must have occurred. Such an approach is semantically better than a catch/throw, but is ugly and is less maintainable than it should be.
While many of the other answers provide good examples of why you might want to catch an rethrow an exception, no one seems to have mentioned a 'finally' scenario.
An example of this is where you have a method in which you set the cursor (for example to a wait cursor), the method has several exit points (e.g. if () return;) and you want to ensure the cursor is reset at the end of the method.
To do this you can wrap all of the code in a try/catch/finally. In the finally set the cursor back to the right cursor. So that you don't bury any valid exceptions, rethrow it in the catch.
try
{
Cursor.Current = Cursors.WaitCursor;
// Test something
if (testResult) return;
// Do something else
}
catch
{
throw;
}
finally
{
Cursor.Current = Cursors.Default;
}
One possible reason to catch-throw is to disable any exception filters deeper up the stack from filtering down (random old link). But of course, if that was the intention, there would be a comment there saying so.
It depends what you are doing in the catch block, and if you are wanting to pass the error on to the calling code or not.
You might say Catch io.FileNotFoundExeption ex and then use an alternative file path or some such, but still throw the error on.
Also doing Throw instead of Throw Ex allows you to keep the full stack trace. Throw ex restarts the stack trace from the throw statement (I hope that makes sense).
In the example in the code you have posted there is, in fact, no point in catching the exception as there is nothing done on the catch it is just re-thown, in fact it does more harm than good as the call stack is lost.
You would, however catch an exception to do some logic (for example closing sql connection of file lock, or just some logging) in the event of an exception the throw it back to the calling code to deal with. This would be more common in a business layer than front end code as you may want the coder implementing your business layer to handle the exception.
To re-iterate though the There is NO point in catching the exception in the example you posted. DON'T do it like that!
Sorry, but many examples as "improved design" still smell horribly or can be extremely misleading. Having try { } catch { log; throw } is just utterly pointless. Exception logging should be done in central place inside the application. exceptions bubble up the stacktrace anyway, why not log them somewhere up and close to the borders of the system?
Caution should be used when you serialize your context (i.e. DTO in one given example) just into the log message. It can easily contain sensitive information one might not want to reach the hands of all the people who can access the log files. And if you don't add any new information to the exception, I really don't see the point of exception wrapping. Good old Java has some point for that, it requires caller to know what kind of exceptions one should expect then calling the code. Since you don't have this in .NET, wrapping doesn't do any good on at least 80% of the cases I've seen.
In addition to what the others have said, see my answer to a related question which shows that catching and rethrowing is not a no-op (it's in VB, but some of the code could be C# invoked from VB).
Most of answers talking about scenario catch-log-rethrow.
Instead of writing it in your code consider to use AOP, in particular Postsharp.Diagnostic.Toolkit with OnExceptionOptions IncludeParameterValue and
IncludeThisArgument
Rethrowing exceptions via throw is useful when you don't have a particular code to handle current exceptions, or in cases when you have a logic to handle specific error cases but want to skip all others.
Example:
string numberText = "";
try
{
Console.Write("Enter an integer: ");
numberText = Console.ReadLine();
var result = int.Parse(numberText);
Console.WriteLine("You entered {0}", result);
}
catch (FormatException)
{
if (numberText.ToLowerInvariant() == "nothing")
{
Console.WriteLine("Please, please don't be lazy and enter a valid number next time.");
}
else
{
throw;
}
}
finally
{
Console.WriteLine("Freed some resources.");
}
Console.ReadKey();
However, there is also another way of doing this, using conditional clauses in catch blocks:
string numberText = "";
try
{
Console.Write("Enter an integer: ");
numberText = Console.ReadLine();
var result = int.Parse(numberText);
Console.WriteLine("You entered {0}", result);
}
catch (FormatException) when (numberText.ToLowerInvariant() == "nothing")
{
Console.WriteLine("Please, please don't be lazy and enter a valid number next time.");
}
finally
{
Console.WriteLine("Freed some resources.");
}
Console.ReadKey();
This mechanism is more efficient than re-throwing an exception because
of the .NET runtime doesn’t have to rebuild the exception object
before re-throwing it.

Handling exceptions thrown by "Dispose" while unwinding nested "using" statements

Apparently, some exceptions may just get lost while using nested using statement. Consider this simple console app:
using System;
namespace ConsoleApplication
{
public class Throwing: IDisposable
{
int n;
public Throwing(int n)
{
this.n = n;
}
public void Dispose()
{
var e = new ApplicationException(String.Format("Throwing({0})", this.n));
Console.WriteLine("Throw: {0}", e.Message);
throw e;
}
}
class Program
{
static void DoWork()
{
// ...
using (var a = new Throwing(1))
{
// ...
using (var b = new Throwing(2))
{
// ...
using (var c = new Throwing(3))
{
// ...
}
}
}
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
// this doesn't get called
Console.WriteLine("UnhandledException:", e.ExceptionObject.ToString());
};
try
{
DoWork();
}
catch (Exception e)
{
// this handles Throwing(1) only
Console.WriteLine("Handle: {0}", e.Message);
}
Console.ReadLine();
}
}
}
Each instance of Throwing throws when it gets disposed of. AppDomain.CurrentDomain.UnhandledException never gets called.
The output:
Throw: Throwing(3)
Throw: Throwing(2)
Throw: Throwing(1)
Handle: Throwing(1)
I prefer to at least be able to log the missing Throwing(2) and Throwing(3). How do I do this, without resorting to a separate try/catch for each using (which would kinda kill the convenience of using)?
In real life, those objects are often instances of classes over which I have no control. They may or may not be throwing, but in case they do, I'd like to have an option to observe such exceptions.
This question came along while I was looking at reducing the level of nested using. There's a neat answer suggesting aggregating exceptions. It's interesting how this is different from the standard behavior of nested using statements.
[EDITED] This question appears to be closely related:
Should you implement IDisposable.Dispose() so that it never throws?
There's a code analyzer warning for this. CA1065, "Do not raise exceptions in unexpected locations". The Dispose() method is on that list. Also a strong warning in the Framework Design Guide, chapter 9.4.1:
AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.).
This goes wrong because the using statement calls Dispose() inside a finally block. An exception raised in a finally block can have an unpleasant side-effect, it replaces an active exception if the finally block was called while the stack is being unwound because of an exception. Exactly what you see happening here.
Repro code:
class Program {
static void Main(string[] args) {
try {
try {
throw new Exception("You won't see this");
}
finally {
throw new Exception("You'll see this");
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
What you are noticing is a fundamental problem in the design of Dispose and using, for which no nice solution as yet exists. IMHO the best design would be to have a version of Dispose which receives as an argument any exception which may be pending (or null, if none is pending), and can either log or encapsulate that exception if it needs to throw one of its own. Otherwise, if you have control of both the code which could cause an exception within the using as well as within the Dispose, you may be able to use some sort of outside data channel to let the Dispose know about the inner exception, but that's rather hokey.
It's too bad there's no proper language support for code associated with a finally block (either explicitly, or implicitly via using) to know whether the associated try completed properly and if not, what went wrong. The notion that Dispose should silently fail is IMHO very dangerous and wrongheaded. If an object encapsulates a file which is open for writing, and Dispose closes the file (a common pattern) and the data cannot be written, having the Dispose call return normally would lead the calling code to believe the data was written correctly, potentially allowing it to overwrite the only good backup. Further, if files are supposed to be closed explicitly and calling Dispose without closing a file should be considered an error, that would imply that Dispose should throw an exception if the guarded block would otherwise complete normally, but if the guarded block fails to call Close because an exception occurred first, having Dispose throw an exception would be very unhelpful.
If performance isn't critical, you could write a wrapper method in VB.NET which would accept two delegates (of types Action and an Action<Exception>), call the first within a try block, and then call the second in a finally block with the exception that occurred in the try block (if any). If the wrapper method was written in VB.NET, it could discover and report the exception that occurred without having to catch and rethrow it. Other patterns would be possible as well. Most usages of the wrapper would involve closures, which are icky, but the wrapper could at least achieve proper semantics.
An alternative wrapper design which would avoid closures, but would require that clients use it correctly and would provide little protection against incorrect usage would have a usage batter like:
var dispRes = new DisposeResult();
...
try
{
.. the following could be in some nested routine which took dispRes as a parameter
using (dispWrap = new DisposeWrap(dispRes, ... other disposable resources)
{
...
}
}
catch (...)
{
}
finally
{
}
if (dispRes.Exception != null)
... handle cleanup failures here
The problem with this approach is that there's no way to ensure that anyone will ever evaluate dispRes.Exception. One could use a finalizer to log cases where dispRes gets abandoned without ever having been examined, but there would be no way to distinguish cases where that occurred because an exception kicked code out beyond the if test, or because the programmer simply forgot the check.
PS--Another case where Dispose really should know whether exceptions occur is when IDisposable objects are used to wrap locks or other scopes where an object's invariants may temporarily be invalidated but are expected to be restored before code leaves the scope. If an exception occurs, code should often have no expectation of resolving the exception, but should nonetheless take action based upon it, leaving the lock neither held nor released but rather invalidated, so that any present or future attempt to acquire it will throw an exception. If there are no future attempts to acquire the lock or other resource, the fact that it is invalid should not disrupt system operation. If the resource is critically necessary to some part of the program, invalidating it will cause that part of the program to die while minimizing the damage it does to anything else. The only way I know to really implement this case with nice semantics is to use icky closures. Otherwise, the only alternative is to require explicit invalidate/validate calls and hope that any return statements within the part of the code where the resource is invalid are preceded by calls to validate.
Maybe some helper function that let you write code similar to using:
void UsingAndLog<T>(Func<T> creator, Action<T> action) where T:IDisposabe
{
T item = creator();
try
{
action(item);
}
finally
{
try { item.Dispose();}
catch(Exception ex)
{
// Log/pick which one to throw.
}
}
}
UsingAndLog(() => new FileStream(...), item =>
{
//code that you'd write inside using
item.Write(...);
});
Note that I'd probably not go this route and just let exceptions from Dispose to overwrite my exceptions from code inside normal using. If library throws from Dispose against strong recommendations not to do so there is a very good chance that it is not the only issue and usefulness of such library need to be reconsidered.

Why can't a 'continue' statement be inside a 'finally' block?

I don't have a problem; I'm just curious. Imagine the following scenario:
foreach (var foo in list)
{
try
{
//Some code
}
catch (Exception)
{
//Some more code
}
finally
{
continue;
}
}
This won't compile, as it raises compiler error CS0157:
Control cannot leave the body of a finally clause
Why?
finally blocks run whether an exception is thrown or not. If an exception is thrown, what the heck would continue do? You cannot continue execution of the loop, because an uncaught exception will transfer control to another function.
Even if no exception is thrown, finally will run when other control transfer statements inside the try/catch block run, like a return, for example, which brings the same problem.
In short, with the semantics of finally it doesn't make sense to allow transferring control from inside a finally block to the outside of it.
Supporting this with some alternative semantics would be more confusing than helpful, since there are simple workarounds that make the intended behaviour way clearer. So you get an error, and are forced to think properly about your problem. It's the general "throw you into the pit of success" idea that goes on in C#.
If you want to ignore exceptions (more often than not is a bad idea) and continue executing the loop, use a catch all block:
foreach ( var in list )
{
try{
//some code
}catch{
continue;
}
}
If you want to continue only when no uncaught exceptions are thrown, just put continue outside the try-block.
Here is a reliable source:
A continue statement cannot exit a finally block (Section 8.10). When
a continue statement occurs within a finally block, the target of the
continue statement must be within the same finally block; otherwise, a
compile-time error occurs.
It is taken from MSDN, 8.9.2 The continue statement.
The documentation say that:
The statements of a finally block are always executed when control leaves a
try statement. This is true whether the control transfer occurs as a
result of normal execution, as a result of executing a break,
continue, goto, or return statement, or as a result of propagating an
exception out of the try statement. If an exception is thrown during
execution of a finally block, the exception is propagated to the next
enclosing try statement. If another exception was in the process of
being propagated, that exception is lost. The process of propagating
an exception is discussed further in the description of the throw statement (Section 8.9.5).
It is from here 8.10 The try statement.
You may think it makes sense, but it doesn't make sense actually.
foreach (var v in List)
{
try
{
//Some code
}
catch (Exception)
{
//Some more code
break; or return;
}
finally
{
continue;
}
}
What do you intend to do a break or a continue when an exception is thrown? The C# compiler team doesn't want to make decision on their own by assuming break or continue. Instead, they decided to complain the developer situation will be ambiguous to transfer control from finally block.
So it is the job of developer to clearly state what he intends to do rather than compiler assuming something else.
I hope you understand why this doesn't compile!
As others have stated, but focused on exceptions, it's really about ambiguous handling of transferring control.
In your mind, you're probably thinking of a scenario like this:
public static object SafeMethod()
{
foreach(var item in list)
{
try
{
try
{
//do something that won't transfer control outside
}
catch
{
//catch everything to not throw exceptions
}
}
finally
{
if (someCondition)
//no exception will be thrown,
//so theoretically this could work
continue;
}
}
return someValue;
}
Theoretically, you can track the control flow and say, yes, this is "ok". No exception is thrown, no control is transferred. But the C# language designers had other issues in mind.
The Thrown Exception
public static void Exception()
{
try
{
foreach(var item in list)
{
try
{
throw new Exception("What now?");
}
finally
{
continue;
}
}
}
catch
{
//do I get hit?
}
}
The Dreaded Goto
public static void Goto()
{
foreach(var item in list)
{
try
{
goto pigsfly;
}
finally
{
continue;
}
}
pigsfly:
}
The Return
public static object ReturnSomething()
{
foreach(var item in list)
{
try
{
return item;
}
finally
{
continue;
}
}
}
The Breakup
public static void Break()
{
foreach(var item in list)
{
try
{
break;
}
finally
{
continue;
}
}
}
So in conclusion, yes, while there is a slight possibility of using a continue in situations where control isn't being transferred, but a good deal (majority?) of cases involve exceptions or return blocks. The language designers felt this would be too ambiguous and (likely) impossible to ensure at compile time that your continue is used only in cases where control flow is not being transferred.
In general continue does not make sense when used in finally block. Take a look at this:
foreach (var item in list)
{
try
{
throw new Exception();
}
finally{
//doesn't make sense as we are after exception
continue;
}
}
"This won't compile and I think it makes complete sense"
Well, I think it doesn't.
When you literally have catch(Exception) then you don't need the finally (and probably not even the continue).
When you have the more realistic catch(SomeException), what should happen when an exception is not caught? Your continue wants to go one way, the exception handling another.
You cannot leave the body of a finally block. This includes break, return and in your case continue keywords.
The finally block can be executed with an exception waiting to be rethrown. It wouldn't really make sense to be able to exit the block (by a continue or anything else) without rethrowing the exception.
If you want to continue your loop whatever happens, you do not need the finally statement: Just catch the exception and don't rethrow.
finally runs whether or not an uncaught exception is thrown. Others have already explained why this makes continue illogical, but here is an alternative that follows the spirit of what this code appears to be asking for. Basically, finally { continue; } is saying:
When there are caught exceptions, continue
When there are uncaught exceptions, allow them to be thrown, but still continue
(1) could be satisfied by placing continue at the end of each catch, and (2) could be satisfied by storing uncaught exceptions to be thrown later. You could write it like this:
var exceptions = new List<Exception>();
foreach (var foo in list) {
try {
// some code
} catch (InvalidOperationException ex) {
// handle specific exception
continue;
} catch (Exception ex) {
exceptions.Add(ex);
continue;
}
// some more code
}
if (exceptions.Any()) {
throw new AggregateException(exceptions);
}
Actually, finally would have also executed in the third case, where there were no exceptions thrown at all, caught or uncaught. If that was desired, you could of course just place a single continue after the try-catch block instead of inside each catch.
Technically speaking, it's a limitation of the underlying CIL. From the language spec:
Control transfer is never permitted to enter a catch handler or finally clause except through the exception handling mechanism.
and
Control transfer out of a protected region is only permitted through an exception instruction (leave, end.filter, end.catch, or end.finally)
On the doc page for the br instruction:
Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction.
This last holds true for all branch instructions, including beq, brfalse, etc.
The designers of the language simply didn't want to (or couldn't) reason about the semantics of a finally block being terminated by a control transfer.
One issue, or perhaps the key issue, is that the finally block gets executed as part of some non-local control transfer (exception processing). The target of that control transfer isn't the enclosing loop; the exception processing aborts the loop and continues unwinding further.
If we have a control transfer out of the finally cleanup block, then the original control transfer is being "hijacked". It gets canceled, and control goes elsewhere.
The semantics can be worked out. Other languages have it.
The designers of C# decided to simply disallow static, "goto-like" control transfers, thereby simplifying things somewhat.
However, even if you do that, it doesn't solve the question of what happens if a dynamic transfer is initiated from a finally: what if the finally block calls a function, and that function throws? The original exception processing is then "hijacked".
If you work out the semantics of this second form of hijacking, there is no reason to banish the first type. They are really the same thing: a control transfer is a control transfer, whether it the same lexical scope or not.

.NET and C# Exceptions. What is it reasonable to catch

Disclaimer, I'm from a Java background. I don't do much C#. There's a great deal of transfer between the two worlds, but of course there are differences and one is in the way Exceptions tend to be thought about.
I recently answered a C# question suggesting that under some circstances it's reasonable to do this:
try {
some work
} catch (Exeption e) {
commonExceptionHandler();
}
(The reasons why are immaterial). I got a response that I don't quite understand:
until .NET 4.0, it's very bad to catch
Exception. It means you catch various
low-level fatal errors and so disguise
bugs. It also means that in the event
of some kind of corruption that
triggers such an exception, any open
finally blocks on the stack will be
executed, so even if the
callExceptionReporter fuunction tries
to log and quit, it may not even get
to that point (the finally blocks may
throw again, or cause more corruption,
or delete something important from the
disk or database).
May I'm more confused than I realise, but I don't agree with some of that. Please would other folks comment.
I understand that there are many low level Exceptions we don't want to swallow. My commonExceptionHandler() function could reasonably rethrow those. This seems consistent with this answer to a related question. Which does say "Depending on your context it can be acceptable to use catch(...), providing the exception is re-thrown." So I conclude using catch (Exception ) is not always evil, silently swallowing certain exceptions is.
The phrase "Until .NET 4 it is very bad to Catch Exception" What changes in .NET 4? IS this a reference to AggregateException, which may give us some new things to do with exceptions we catch, but I don't think changes the fundamental "don't swallow" rule.
The next phrase really bothers be. Can this be right?
It also means that in the event
of some kind of corruption that
triggers such an exception, any open
finally blocks on the stack will be
executed (the finally blocks may
throw again, or cause more corruption,
or delete something important from the
disk or database)
My understanding is that if some low level code had
lowLevelMethod() {
try {
lowestLevelMethod();
} finally {
some really important stuff
}
}
and in my code I call lowLevel();
try {
lowLevel()
} catch (Exception e) {
exception handling and maybe rethrowing
}
Whether or not I catch Exception this has no effect whatever on the excution of the finally block. By the time we leave lowLevelMethod() the finally has already run. If the finally is going to do any of the bad things, such as corrupt my disk, then it will do so. My catching the Exception made no difference. If It reaches my Exception block I need to do the right thing, but I can't be the cause of dmis-executing finallys
For the question #2:
The author meant "Corrupted State Exceptions". They will be introduced in .NET 4.0 (CLR team announced this at PDC 2008 in this talk).
Corrupted state exceptions cannot be caught by normal catch block. Examples: Access violation, Invalid Memory.
But you might want to catch these exceptions:
In main() – write to log, exit, turn off addin
Very rare cases when you know that code throws exception like this (e.g. some cases with interop with native code)
To do this you should put attribute [HandleProcessCorruptedStateException] at the method where you want to catch CorruptedStateException.
To read more about these exceptions please see this MSDN article.
As a general rule you shouldn't catch exceptions unless:
You have a specific exception that you can handle and do something about. However in this case you should always check whether you shouldn't be trying to account for and avoid the exception in the first place.
You are at the top level of an application (for instance the UI) and do not want the default behaviour to be presented to the user. For instance you might want an error dialog with a "please send us your logs" style message.
You re-throw the exception after dealing with it somehow, for instance if you roll back a DB transaction.
Your finally blocks always execute. Your code sample is correct - the low level method should just have try and finally. For instance an unmanaged call might know that it needs to dispose of the unmanaged resource, but this wouldn't be exposed to .Net methods calling it. That call should get rid of the unmanaged resource in its finally block, and calling managed methods can handle exceptions or just pass them on up.
If there's something in an exception that you need to handle you should re-throw the exception, for instance:
try {
conn.BeginTransaction();
//do stuff
conn.CommitTransaction();
}
catch (Exception) {
conn.RollbackTransaction(); //required action on any exception
throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
conn.Dispose(); //always dispose of the resource
}
My motto is handle what you can (or need to) and let any other exceptions bubble up and catch them in an UnhandledException event.
You are correct tho, a finally block is always called (even in the event of an exception being raised in the try section) before you exit the method. So whether you want to the catch the exception on the out method or not is entirely up to you.....this should not affect the finally block being called.
Just to your third question:
If you have
nastyLowLevel() {
doSomethingWhichMayCorruptSomethingAndThrowsException();
}
MyEvilCatcher() {
try {
nastyLowLevel();
} catch (Exception e) {
MyExceptionHandler(e);
}
}
WiseCatcher() {
try {
MyEvilCatcher();
} catch (LowLevelException e) {
DoSomethingWiseSoFinnalyDontRuinAnything();
} finally {
DoSomethingWhichAssumesLowLevelWentOk();
}
}
I think the response you asked about just meant that some low level methods could use exceptions to inform some outer method that special care has to be taken. If you forget about this exceptions in your catch-all-handler and don't rethrow them, something might go wrong.
Generally, I prefer thinking carefully about which exceptions can possibly be thrown and catch them explicitely. I only use "generic handler" at the very outer level in production environments in order to log unexpected exception and present them to the customer in an well-formatted manner (including a hint to send us the log file.)
I think the quoted response is wrong (or maybe meant 2.0 instead of 4.0)? It sounds kinda bogus to me.

Will code in a Finally statement fire if I return a value in a Try block?

I'm reviewing some code for a friend and say that he was using a return statement inside of a try-finally block. Does the code in the Finally section still fire even though the rest of the try block doesn't?
Example:
public bool someMethod()
{
try
{
return true;
throw new Exception("test"); // doesn't seem to get executed
}
finally
{
//code in question
}
}
Simple answer: Yes.
Normally, yes. The finally section is guaranteed to execute whatever happens including exceptions or return statement. An exception to this rule is an asynchronous exception happening on the thread (OutOfMemoryException, StackOverflowException).
To learn more about async exceptions and reliable code in that situations, read about constrained execution regions.
Here's a little test:
class Class1
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("before");
Console.WriteLine(test());
Console.WriteLine("after");
}
static string test()
{
try
{
return "return";
}
finally
{
Console.WriteLine("finally");
}
}
}
The result is:
before
finally
return
after
Quoting from MSDN
finally is used to guarantee a statement block of code executes regardless of how the preceding try block is exited.
Generally yes, the finally will run.
For the following three scenarios, the finally will ALWAYS run:
No exceptions occur
Synchronous exceptions (exceptions that occur in normal program flow).
This includes CLS compliant exceptions that derive from System.Exception and non-CLS compliant exceptions, which do not derive from System.Exception. Non-CLS compliant exceptions are automatically wrapped by the RuntimeWrappedException. C# cannot throw non-CLS complaint exceptions, but languages such as C++ can. C# could be calling into code written in a language that can throw non-CLS compliant exceptions.
Asynchronous ThreadAbortException
As of .NET 2.0, a ThreadAbortException will no longer prevent a finally from running. ThreadAbortException is now hoisted to before or after the finally. The finally will always run and will not be interrupted by a thread abort, so long as the try was actually entered before the thread abort occurred.
The following scenario, the finally will not run:
Asynchronous StackOverflowException.
As of .NET 2.0 a stack overflow will cause the process to terminate. The finally will not be run, unless a further constraint is applied to make the finally a CER (Constrained Execution Region). CERs should not be used in general user code. They should only be used where it is critical that clean-up code always run -- after all the process is shutting down on stack overflow anyway and all managed objects will therefore be cleaned-up by default. Thus, the only place a CER should be relevant is for resources that are allocated outside of the process, e.g., unmanaged handles.
Typically, unmanaged code is wrapped by some managed class before being consumed by user code. The managed wrapper class will typically make use of a SafeHandle to wrap the unmanaged handle. The SafeHandle implements a critical finalizer, and a Release method that is run in a CER to guarantee the execution of the clean-up code. For this reason, you should not see CERs littered through-out user code.
So the fact that the finally doesn't run on StackOverflowException should have no effect to user code, since the process will terminate anyway. If you have some edge case where you do need to clean-up some unmanaged resource, outside of a SafeHandle or CriticalFinalizerObject, then use a CER as follows; but please note, this is bad practice -- the unmanaged concept should be abstracted to a managed class(es) and appropriate SafeHandle(s) by design.
e.g.,
// No code can appear after this line, before the try
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// This is *NOT* a CER
}
finally
{
// This is a CER; guaranteed to run, if the try was entered,
// even if a StackOverflowException occurs.
}
There's a very important exception to this which I haven't seen mentioned in any other answers, and which (after programming in C# for 18 years) I can't believe I didn't know.
If you throw or trigger an exception of any sort inside your catch block (not just weird StackOverflowExceptions and things of that ilk), and you don't have the entire try/catch/finally block inside another try/catch block, your finally block won't execute. This is easily demonstrated - and if I hadn't seen it myself, given how often I've read that it's only really weird, tiny corner-cases that can cause a finally block not to execute, I wouldn't have believed it.
static void Main(string[] args)
{
Console.WriteLine("Beginning demo of how finally clause doesn't get executed");
try
{
Console.WriteLine("Inside try but before exception.");
throw new Exception("Exception #1");
}
catch (Exception ex)
{
Console.WriteLine($"Inside catch for the exception '{ex.Message}' (before throwing another exception).");
throw;
}
finally
{
Console.WriteLine("This never gets executed, and that seems very, very wrong.");
}
Console.WriteLine("This never gets executed, but I wasn't expecting it to.");
Console.ReadLine();
}
I'm sure there's a reason for this, but it's bizarre that it's not more widely known. (It's noted here for instance, but not anywhere in this particular question.)
I realize I'm late to the party but in the scenario (differing from the OP's example) where indeed an exception is thrown MSDN states (https://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx): "If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation."
The finally block is only guaranteed to execute if some other function (such as Main) further up the call stack catches the exception. This detail is usually not a problem because all run time environments (CLR and OS) C# programs run on free most resources a process owns when it exits (file handles etc.). In some cases it may be crucial though: A database operation half underway which you want to commit resp. unwind; or some remote connection which may not be closed automatically by the OS and then blocks a server.
Yes. That is in fact that main point of a finally statement. Unless something catestrophic occurs (out of memory, computer unplugged, etc.) the finally statement should always be executed.
It will also not fire on uncaught exception and running in a thread hosted in a Windows Service
Finally is not executed when in a Thread running in a Windows Service
finally wont run in case if you are exiting from the application using
System.exit(0); as in
try
{
System.out.println("try");
System.exit(0);
}
finally
{
System.out.println("finally");
}
the result would be just :
try
99% of the scenarios it will be guaranteed that the code inside the finally block will run, however, think of this scenario: You have a thread that has a try->finally block (no catch) and you get an unhandled exception within that thread. In this case, the thread will exit and its finally block will not be executed (the application can continue to run in this case)
This scenario is pretty rare, but it's only to show that the answer is not ALWAYS "Yes", it's most of the time "Yes" and sometimes, in rare conditions, "No".
The main purpose of finally block is to execute whatever is written inside it. It should not depend upon whatever happens in try or catch.However with System.Environment.Exit(1) the application will exit without moving to next line of code.

Categories