exception thrown inside a finally clause

A

Andy Fish

Dear C# gurus. consider the folowing code:

try {
try {
throw new Exception("a");
} finally {
throw new Exception("b");
}
} catch (Exception e) {
Debug.WriteLine(e);
}

When I tried this in visual studio 2008 (.net 3.5), the exception
caught by the exception handler is "b". Section 23.3 of the ECMA 334
C# language specification helpfully says "The behavior of uncaught
exceptions that occur during finalizer execution is unspecified."

If some unexpected event happens, I would expect the exception seen by
the outside world would be the original one, not something that
happened as a side effect of clearing up. This is what java does by
design and I don't see any justification for the current behaviour.

OTTOMH the only way i can think of to solve this problem is something
like this:

bool exceptionInTryBlock = true;
try
{
main body of try block
exceptionInTryBlock = false;
} finally {
try {
} catch (Exception e) {
if (!exceptionInTryBlock) {
throw e;
}
}
}

but I need to do this for every try/finally block in the code (and
even then I get hit by the bug that rethrowing an exception wipes out
the original stack trace).

Since C# is designed to be used for production applications, surely
someone else has solved this problem before? any clues much
appreciated please. am I doing something fundamentally wrong in my
whole approach to exception handling?
 
D

dunawayc

but I need to do this for every try/finally block in the code (and
even then I get hit by the bug that rethrowing an exception wipes out
the original stack trace).

As far as an exception being thrown in the finally block, I can't give
you an answer. You pointed out yourself that the spec says that what
happens in such a case is unspecified.

In order to preserve the stack trace when rethrowing an exception,
just use throw by itself, without the exception variable.

(i.e.)
try {
} catch (Exception e) {
if (!exceptionInTryBlock) {
throw; //<------------ Omit the variable after throw and
the stack trace will be preserved.
}
}

Chris
 
D

dunawayc

but I need to do this for every try/finally block in the code (and
even then I get hit by the bug that rethrowing an exception wipes out
the original stack trace).

As far as an exception being thrown in the finally block, I can't give
you an answer. You pointed out yourself that the spec says that what
happens in such a case is unspecified.

In order to preserve the stack trace when rethrowing an exception,
just use throw by itself, without the exception variable.

(i.e.)
try {
} catch (Exception e) {
if (!exceptionInTryBlock) {
throw; //<------------ Omit the variable after throw and
the stack trace will be preserved.
}
}

Chris
 
A

Andy Fish

In order to preserve the stack trace when rethrowing an exception,
just use throw by itself, without the exception variable.

(i.e.)
try {
   } catch (Exception e) {
      if (!exceptionInTryBlock) {
         throw;     //<------------ Omit the variable afterthrow and
the stack trace will be preserved.
      }
   }

Chris

partly true - this resets the top frame of the stack trace but leaves
lower frames intact.

however, my main concern is how to ensure an exception thrown during
the finally clause doesn't mask a genuine exception
 
A

Andy Fish

In order to preserve the stack trace when rethrowing an exception,
just use throw by itself, without the exception variable.

(i.e.)
try {
   } catch (Exception e) {
      if (!exceptionInTryBlock) {
         throw;     //<------------ Omit the variable afterthrow and
the stack trace will be preserved.
      }
   }

Chris

partly true - this resets the top frame of the stack trace but leaves
lower frames intact.

however, my main concern is how to ensure an exception thrown during
the finally clause doesn't mask a genuine exception
 
R

Registered User

Dear C# gurus. consider the folowing code:

try {
try {
throw new Exception("a");
} finally {
throw new Exception("b");
}
} catch (Exception e) {
Debug.WriteLine(e);
}

When I tried this in visual studio 2008 (.net 3.5), the exception
caught by the exception handler is "b". Section 23.3 of the ECMA 334
C# language specification helpfully says "The behavior of uncaught
exceptions that occur during finalizer execution is unspecified."

If some unexpected event happens, I would expect the exception seen by
the outside world would be the original one, not something that
happened as a side effect of clearing up. This is what java does by
design and I don't see any justification for the current behaviour.

OTTOMH the only way i can think of to solve this problem is something
like this:
You might want to verify how Java code behaves in the described
scenario before deciding your problem is a C# issue.
bool exceptionInTryBlock = true;
try
{
main body of try block
exceptionInTryBlock = false;
} finally {
try {
} catch (Exception e) {
if (!exceptionInTryBlock) {
throw e;
}
}
}

but I need to do this for every try/finally block in the code (and
even then I get hit by the bug that rethrowing an exception wipes out
the original stack trace).

Since C# is designed to be used for production applications, surely
someone else has solved this problem before? any clues much
appreciated please. am I doing something fundamentally wrong in my
whole approach to exception handling?

The "need to do this for every try/finally block in the code" should
suggest your approach needs to be reconsidered. At least the current
scheme could be changed to something like this ...
try
{
try
{
}
catch(Exception ex)
{
// exceptions generated in the try block
// will be caught here
}
finally
{
}
catch(Exception ex)
{
// exceptions generated in the inner catch and
// finally blocks will be caught here
}

It appears you're trying to catch any and every exception that might
be generated at any point in the application. There is no distinction
between exception types and the severity of the specific exception.
This is not a good path to follow. I would suggest reading the article
'Exceptions and Exception Handling'
http://msdn.microsoft.com/en-us/library/ms173160.aspx
and its related topics to get a better understanding of exception
handling.

regards
A.G.
 
R

Registered User

Dear C# gurus. consider the folowing code:

try {
try {
throw new Exception("a");
} finally {
throw new Exception("b");
}
} catch (Exception e) {
Debug.WriteLine(e);
}

When I tried this in visual studio 2008 (.net 3.5), the exception
caught by the exception handler is "b". Section 23.3 of the ECMA 334
C# language specification helpfully says "The behavior of uncaught
exceptions that occur during finalizer execution is unspecified."

If some unexpected event happens, I would expect the exception seen by
the outside world would be the original one, not something that
happened as a side effect of clearing up. This is what java does by
design and I don't see any justification for the current behaviour.

OTTOMH the only way i can think of to solve this problem is something
like this:
You might want to verify how Java code behaves in the described
scenario before deciding your problem is a C# issue.
bool exceptionInTryBlock = true;
try
{
main body of try block
exceptionInTryBlock = false;
} finally {
try {
} catch (Exception e) {
if (!exceptionInTryBlock) {
throw e;
}
}
}

but I need to do this for every try/finally block in the code (and
even then I get hit by the bug that rethrowing an exception wipes out
the original stack trace).

Since C# is designed to be used for production applications, surely
someone else has solved this problem before? any clues much
appreciated please. am I doing something fundamentally wrong in my
whole approach to exception handling?

The "need to do this for every try/finally block in the code" should
suggest your approach needs to be reconsidered. At least the current
scheme could be changed to something like this ...
try
{
try
{
}
catch(Exception ex)
{
// exceptions generated in the try block
// will be caught here
}
finally
{
}
catch(Exception ex)
{
// exceptions generated in the inner catch and
// finally blocks will be caught here
}

It appears you're trying to catch any and every exception that might
be generated at any point in the application. There is no distinction
between exception types and the severity of the specific exception.
This is not a good path to follow. I would suggest reading the article
'Exceptions and Exception Handling'
http://msdn.microsoft.com/en-us/library/ms173160.aspx
and its related topics to get a better understanding of exception
handling.

regards
A.G.
 
A

Andy Fish

You might want to verify how Java code behaves in the described
scenario before deciding your problem is a C# issue.








The "need to do this for every try/finally block in the code" should
suggest your approach needs to be reconsidered. At least the current
scheme could be changed to something like this ...
try
{
    try
    {
    }
    catch(Exception ex)
    {
         // exceptions generated in the try block
         // will be caught here
    }
   finally
   {
    }
catch(Exception ex)
{
         // exceptions generated in the inner catch and
         // finally blocks will be caught here

}

It appears you're trying to catch any and every exception that might
be generated at any point in the application. There is no distinction
between exception types and the severity of the specific exception.
This is not a good path to follow. I would suggest reading the article
'Exceptions and Exception Handling'http://msdn.microsoft.com/en-us/library/ms173160.aspx
and its related topics to get a better understanding of exception
handling.

regards
A.G.- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Thanks for these responses (and thanks to peter for pointing out that
a finalizer is not the same as a finally clause - that means my
scenario is not actually covered by the C# specification at all).
Also, I just re-checked the java specification and I was wrong before
- it explicitly prescribes the behaviour I'm seeing in C#.

the overall design that I am trying to achieve is not to catch any
exceptions at all (i.e. any exception that happens should be
propagated up as normal) but that resources are always released (as
well as can be done) when the method returns

if an exception happens during the finally clause, I would normally
expect it to be propagated - that's why I don't really want to put a
catch inside my finally.

However, if the method is exiting due to an exception in the try
block, i want to make sure that the exception that gets propagated is
the one from the try block, not the one from the finally block

it seems to me this would be a very common idiom - in fact for the
majority of code I can't see why you'd want it any other way

the problem is that if a finally block is being executed as a result
of an exception in the try block, the set of resources used by that
function could be in any number of intermediate states, so it's very
difficult to code the finally block to handle all of these (and
testing it would be a nightmare because you'd need to simulate an
exception on almost every line to see what happened)

the particular case in point was some kind of database error occurring
which caused an exception in the main block. The finally clause tried
to close the database connection but this failed because the database
said the connection was not open, and now i have no idea what the
orignal database error was
 
A

Andy Fish

You might want to verify how Java code behaves in the described
scenario before deciding your problem is a C# issue.








The "need to do this for every try/finally block in the code" should
suggest your approach needs to be reconsidered. At least the current
scheme could be changed to something like this ...
try
{
    try
    {
    }
    catch(Exception ex)
    {
         // exceptions generated in the try block
         // will be caught here
    }
   finally
   {
    }
catch(Exception ex)
{
         // exceptions generated in the inner catch and
         // finally blocks will be caught here

}

It appears you're trying to catch any and every exception that might
be generated at any point in the application. There is no distinction
between exception types and the severity of the specific exception.
This is not a good path to follow. I would suggest reading the article
'Exceptions and Exception Handling'http://msdn.microsoft.com/en-us/library/ms173160.aspx
and its related topics to get a better understanding of exception
handling.

regards
A.G.- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Thanks for these responses (and thanks to peter for pointing out that
a finalizer is not the same as a finally clause - that means my
scenario is not actually covered by the C# specification at all).
Also, I just re-checked the java specification and I was wrong before
- it explicitly prescribes the behaviour I'm seeing in C#.

the overall design that I am trying to achieve is not to catch any
exceptions at all (i.e. any exception that happens should be
propagated up as normal) but that resources are always released (as
well as can be done) when the method returns

if an exception happens during the finally clause, I would normally
expect it to be propagated - that's why I don't really want to put a
catch inside my finally.

However, if the method is exiting due to an exception in the try
block, i want to make sure that the exception that gets propagated is
the one from the try block, not the one from the finally block

it seems to me this would be a very common idiom - in fact for the
majority of code I can't see why you'd want it any other way

the problem is that if a finally block is being executed as a result
of an exception in the try block, the set of resources used by that
function could be in any number of intermediate states, so it's very
difficult to code the finally block to handle all of these (and
testing it would be a nightmare because you'd need to simulate an
exception on almost every line to see what happened)

the particular case in point was some kind of database error occurring
which caused an exception in the main block. The finally clause tried
to close the database connection but this failed because the database
said the connection was not open, and now i have no idea what the
orignal database error was
 
B

Ben Voigt [C++ MVP]

it seems to me this would be a very common idiom - in fact for the
majority of code I can't see why you'd want it any other way

the problem is that if a finally block is being executed as a result
of an exception in the try block, the set of resources used by that
function could be in any number of intermediate states, so it's very
difficult to code the finally block to handle all of these (and
testing it would be a nightmare because you'd need to simulate an
exception on almost every line to see what happened)

You're right -- this is a very common situation, and try/finally isn't a
very good way of getting it done. That's why there's a pattern (Disposable)
and a keyword (using statement) to solve exactly this issue.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top