Logic throwing

try { try { throw new Exception("From Try"); } catch { throw new Exception("From Catch"); } finally { throw new Exception("From Finally"); } } catch (Exception ex) { Console.WriteLine(ex.Message); } 

The above code output: From Finally .

Why is it not From Catch ?

-or -

How can I catch and log both exceptions externally?

+4
source share
8 answers

Since the finally block is executed after the catch block, overriding the exception.

And when an exception occurs during the processing of an earlier one, the first one is lost.

How can I catch and log both exceptions externally?

  • The does not throw inside the finally block. This is always a bad idea.
  • If you want to register an internal catch block, use throw; or throw the first exception as an InnerException of the new one. This is why there is an InnerException .
+6
source

This behavior, as it is defined by the C # language specification. Exceptions thrown inside the try block are interrupted and the exception raised in the finally block will be processed instead.

The relevant section is 8.9.5. The throw statement explains how exceptions are propagated:

  • In the current member of the function, each try that encloses a cast point is considered. For each S statement, starting with the innermost try and ending with the outer try , the following steps are evaluated:

    • If the try block from S encloses a cast point, and if S has one or more catch , the catch are checked in order of appearance to find a suitable handler for the exception. The first catch clause, which indicates the type of exception or the base type of the type of exception, is considered a match. The general catch clause ( ยง8.10 ) is considered a match for any type of exception. If a suitable catch clause is found, the distribution of exceptions ends with passing control to the block of this catch clause.

    • Otherwise, if a try or catch block of an S block encloses a cast point, and if S has a final block, control is passed to the finally block. If the finally block throws another exception, the processing of the current exception ends. Otherwise, when control reaches the endpoint of the finally block, processing of the current exception continues.

+3
source

Add an extra layer of try-catch blocks, for example:

 try { Exception fromCatch = null; try { throw new Exception("From Try"); } catch { try { throw new Exception("From Catch"); } catch (Exception e) { // catch failed -> store exception fromCatch = e; } } finally { try { throw new Exception("From Finally"); } catch (Exception e) { // i can think of better exception merging... but this shows the idea throw new Exception(e.Message, fromCatch); } // throw fromCatch, in case "From Finally did not happen" throw fromCatch; } } catch (Exception ex) { Console.WriteLine(ex.Message); if (ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); } } 

Reports:

 From Finally From Catch 

Editing: this is obviously the answer to the second question, since the โ€œwhyโ€ have been answered enough :)

+1
source

finally always executed; and he always works last. Thus, the lat made by an internal attempt was final, and it threw something that was captured by an external catch

not sure if i understand part 2 of the question

0
source

finally happens no matter what. Regardless of whether there was an exception in the attempt or trick. So you see "From the end." (Actually, this is the whole purpose of the finally clause. Thus, you can put code there that will clear resources, etc. Regardless, even if there is an exception.)

0
source

Your code throws a new Exception from each part of the try / catch / finally statement. When you create a new error, you are essentially swallowing the previous exception. You can add your โ€œFrom Catchโ€ message to the โ€œFrom Catchโ€ message with something like

 catch(Exception ex) { throw new Exception(ex.Message + ":" + "From Catch"); } 

I don't know how you could tie this in the end, though.

0
source

Because the finally block is always executed.

 try { try { throw new Exception("From Try"); // (1) A new exception object A is created here and thrown. } catch // (2) Exception object A is catched. { throw new Exception("From Catch"); // (3) A new exception object B is created here and thrown. } finally // (4) Execution is forced to continue here! { throw new Exception("From Finally"); // (5) A new exception object C is created here and thrown. } } catch (Exception ex) // (6) Exception object C is catched. { Console.WriteLine(ex.Message); } 

Each new exception object in step (3) and (5) discards the previous one. Since the finally block is always executed, all that remains is the C object of the exception from step (5).

0
source

This is a very good question, and it is rather complicated. Skip this step by step:

 try { throw new Exception("From Try"); } catch { throw new Exception("From Catch"); } 

In the above code, an Exception ("From Try") is thrown and caught by a catch clause (pretty simple so far). The catch clause throws an exception from it, which we usually expect (because the catch is nested in a larger try-catch block) to be caught immediately, but ...

 finally { throw new Exception("From Finally"); } 

The finally clause, which is guaranteed to (try) to execute, comes first, and throws an exception from its own, overwriting the exception ("From Catch") that was thrown earlier.

"The usual use of the catch and, finally, together is to receive and use resources in the try block, exceptional circumstances in the catch to block and free resources in the finally block" - MSDN Article

Following this logical principle, we should try to refrain from writing code in our catch and, finally, blocks that are not prone to errors. If you are concerned about a situation like the one you presented, I recommend that you log exceptions and their related information to an external file that you can reference debugging.

0
source

All Articles