static void Main(string[] args)
{
try
{
var intValue = "test";
var test = Convert.ToInt32(intValue);
}
catch (FormatException)
{
Console.WriteLine("format exception");
throw;
}
catch (Exception)
{
}
finally
{
Console.WriteLine("finally");
}
}
According to me, during conversion from string to int, a FormatException is thrown. Now inside the catch block, we are re throwing the original exception. Why is this not caught in the generic exception catch block? If I put try/catch around the throw then application doesn't crashes.
Why is this not caught in the generic exception catch block?
Because the generic exception block catches exceptions that are thrown only within the try block and doesn't catch exceptions thrown from catch blocks.
So if you intend to throw an exception from the catch block and you want to handle it, you will need to wrap the calling code in yet another try/catch.
Related
it is allowed to use custom exception, where the exception can be thrown like below.
try
{
int foo = int.Parse(token);
}
catch (FormatException ex)
{
//Assuming you added this constructor
throw new ParserException(
$"Failed to read {token} as number.",
FileName,
LineNumber,
ex);
}
But in a normal try catch block, it says , throwing exceptions will clear the stacktrace.
try
{
ForthCall();
}
catch (Exception ex)
{
throw ex;
}
So in custom exception,how it managed to use throw exception, without clear the stacktrace?
There are several ways this can be done.
As mentioned in this link In C#, how can I rethrow InnerException without losing stack trace?, you can use the ExceptionDispatchInfo Class
with code similar to
try
{
task.Wait();
}
catch(AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
Another way is to have your handler return a boolean, whether the exception was handled or not, so you can use this in your catch clause:
catch (Exception ex) {
if (!HandleException(ex)) {
throw;
}
}
where HandleException is your custom Exception handler. Gotten from this link: How to throw exception without resetting stack trace?
Whenever you use throw with an exception object, it fills in the stack trace at that point. (Compare to Java, which populates stack traces when an exception is constructed.)
If you use throw without an exception object, which you can only do in a catch clause, the caught exception object is re-throw without alteration.
Ok, as far as I understand, try/catch blocks try an operation and catch blocks catch exceptions. The more specific exceptions go up top, the more generic towards the bottom of the series of catch blocks. In the following code, I implement try/catch, everything works fine.
As far as I understand, a finally block always executes. Some people have argued that there is no purpose to finally block, because if there is an exception or there isn't, the code after the last catch block gets executed anyways.
However, the argument against this is that if there is an exception thrown in a catch block, there are no subsequent catch blocks to catch that exception. So by putting resource cleanup code in a finally block, you ensure that resources will be released in the event that an exception is thrown in a catch block.
Which is why the following code puzzles me. I throw an exception in the first catch block and the finally block never executes. Why?
*Please note that there is indeed an exception thrown while creating myStreamReader, as the file is actually called generic.txt and is misspelled with purpose, in order to throw the initial exception.
StreamReader myStreamReader = null;
try
{
myStreamReader = new StreamReader("c:\\genneric.txt");
Console.WriteLine(myStreadReader.ReadToEnd());
}
catch(FileNotFoundException Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
throw new Exception();
}
catch(Exception Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
}
finally
{
if(myStreamReader != null)
{
myStreamReader.Close();
}
Console.WriteLine("Closed the StreamReader.");
}
VIDEO:
The issue with this block of code originates in this video, at the 27:20 mark:
https://www.youtube.com/watch?v=WxdSb3ZCWYc&list=PLAC325451207E3105&index=41
The guy directly declares that an Exception that occurs in a catch block will not prevent the finally block from executing. I am seeing that it does.
If that new exception is completely unhandled, the entire process is torn down, and the finally block never gets to run.
If there's some other exception handler at a higher level, or an unhandled exception handler has been installed, the finally block does run.
This sample does show "Closed the StreamReader":
static void Main()
{
try
{
StreamReader myStreamReader = null;
try
{
myStreamReader = new StreamReader("c:\\genneric.txt");
Console.WriteLine(myStreamReader.ReadToEnd());
}
catch (FileNotFoundException Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
throw new Exception();
}
catch (Exception Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
}
finally
{
if (myStreamReader != null)
{
myStreamReader.Close();
}
Console.WriteLine("Closed the StreamReader.");
}
}
catch
{
}
Console.WriteLine("Done");
Console.ReadLine();
}
Unhandled exception handlers can be registered in the AppDomain.UnhandledException event.
Your understanding is not correct. See try-finally.
By using a finally block, you can clean up any resources that are
allocated in a try block, and you can run code even if an exception
occurs in the try block. Typically, the statements of a finally block
run when control leaves a try statement. The transfer of control can
occur as a result of normal execution, of execution of a break,
continue, goto, or return statement, or of propagation of an exception
out of the try statement.
So finally does executed if you return for instance out of a try block, but not if you throw from a catch block.
However, if the exception is unhandled, execution of the finally block
is dependent on how the exception unwind operation is triggered. That,
in turn, is dependent on how your computer is set up.
Assuming the file is not found, it would first catch the FileNotFoundException:
catch(FileNotFoundException error)
{
Console.WriteLine(error.Message);
Console.WriteLine();
throw new Exception();
}
This writes a message to the console, and then throws a new Exception. This exception however, is unhandled and will halt execution. If you throw an exception from within a Catch block, it will not be caught by any subsequent blocks.
The solution is to handle the exception appropiately instead of throwing a new one. If the file was not found, then act upon it, e.g. let the user choose another file, create the file, etc.
use throw instead and try this. When you throw a new exception, the actual exception will be lost. But when you use just throw it will throw the actual exception which is FileNotFoundException.
StreamReader myStreamReader = null;
try
{
myStreamReader = new StreamReader("c:\\genneric.txt");
Console.WriteLine(myStreadReader.ReadToEnd());
}
catch(FileNotFoundException Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
throw;
}
catch(Exception Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
}
finally
{
Console.WriteLine("Closing the StreamReader.");
try{
if(myStreamReader != null)
{
myStreamReader.Close();
}
} catch(Exception e) { Console.WriteLine(e.ToString()) };
}
}
I am trying to log errors to a file but I can't seem to get the catch block to run when an error occurs. Here is an example of the code:
try
{
cmd.ExecuteNonQuery();
}
catch (MySQLException ex)
{
//run some logging code
}
finally
{
//clean up the resources
}
The problem is when there is an exception, I get the error thrown from the built in webserver that its an unhandled exception. When I debug the code stops at the exception then continues on to the finally block. Can someone point me in the right direction here?
ExecuteNonQuery() throws an exception of type SqlException.
So I'm not sure what MySQLException is, but you need to be catching an SqlException.
Look at this for extra info:
SqlCommand.ExecuteNonQuery Method
SqlException Class.
It seems like the exception thrown is not not of type MySQLException or any exception derived from it. So the catch block never never catches it and the finally block is executed directly!
To check what kind of exception was raised, modify the code to:
try
{
cmd.ExecuteNonQuery();
}
catch (MySQLException ex)
{
//run some logging code
}
catch (Exception ex)
{
// any other exception will be handled here
}
finally
{
//clean up the resources
}
That method can throw different types of exceptions
InvalidCastException
SqlException
IOException
InvalidOperationException
ObjectDisposedException
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's output is: From Finally.
Why it's not From Catch?
-or-
How can i catch & log from outside both exceptions?
Because the finally block executes after the catch block, overriding the exception.
And when an exception happens during the handling of an earlier one, the first one is lost.
How can i catch & log from outside both exceptions?
By not throwing inside a finally block. That is always a bad idea.
If you want to log in an inner catch block use throw; or pass the first exception as InnerException of the new one. That is why InnerException exists.
This is the behaviour as it is defined by the C# language specification. Handling of the exception thrown inside the try block is aborted and instead the exception thrown in the finally block will be handled.
The relevant section 8.9.5 The throw statement explains how exceptions are propagates:
In the current function member, each try statement that encloses the throw point is examined. For each statement S, starting with the innermost try statement and ending with the outermost try statement, the following steps are evaluated:
If the try block of S encloses the throw point and if S has one or more catch clauses, the catch clauses are examined in order of appearance to locate a suitable handler for the exception. The first catch clause that specifies the exception type or a base type of the exception type is considered a match. A general catch clause (ยง8.10) is considered a match for any exception type. If a matching catch clause is located, the exception propagation is completed by transferring control to the block of that catch clause.
Otherwise, if the try block or a catch block of S encloses the throw point and if S has a finally block, control is transferred to the finally block. If the finally block throws another exception, processing of the current exception is terminated. Otherwise, when control reaches the end point of the finally block, processing of the current exception is continued.
Add an extra layer of try-catch blocks like the following:
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
Edit: this is obviously the answer for question two, as the "why" is answered sufficiently :)
finally always runs; and it always runs last. So the lat thing done by the inner try was the finally and that threw something that was caught by the outer catch
not sure if i understand part2 of the question
finally happens no matter what. Regardless of whether there was an exception in the try or catch. Thus, you see "From Finally". (This actually is the entire purpose of the finally clause. So you can put code in there that will clean up resources and the like no matter what -- even if there's an exception.)
Your code throws a new Exception from each part of the try/catch/finally statement. You are essentially swallowing the previous exception when you create the new error. You can add your "From Try" message to your "From Catch" message with something like
catch(Exception ex)
{
throw new Exception(ex.Message + ":" + "From Catch");
}
I don't know know how you could chain that in the finally though.
This is a very good question, and one that is kind of tricky. Let's go through this step by step:
try
{
throw new Exception("From Try");
}
catch
{
throw new Exception("From Catch");
}
In the code above, Exception("From Try") is thrown and caught by the catch clause (pretty simple so far). The catch clause throws an exception of it's own, which normally we would 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 of it's own, overwriting the Exception("From Catch") that was thrown earlier.
"A common usage of catch and finally
together is to obtain and use
resources in a try block, deal with
exceptional circumstances in a catch
block, and release the resources in
the finally block" - MSDN Article
Following this train of logic, we should try our best to refrain from writing code in our catch and finally blocks that is exception-prone. If you're worried about situations like the one you presented cropping up, I'd recommend logging the exceptions and their related information out to an external file, which you can reference for debugging.
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);
}
Every new'd exception object in step (3) and (5) discards the previous one. Since the finally block is always executed all what remains is the exception object C from step (5).
I have an aspx page that, on a button click, creates an instance of a serviceRefernece object. In the code behind for my page I have the call wrapped in a try/catch.
try
{
var client = GetClient();
var request = new ActiveVerificationRequestDC();
var response = client.GetActiveVerification(request);
DoSomethingWithTheResponse(response);
}
catch (FaultException ex)
{
LogError(ex, MethodBase.GetCurrentMethod().Name);
throw;
}
catch (Exception ex)
{
var args = new[] { MethodBase.GetCurrentMethod().Name, ex.Message };
DisplayError(args);
}
The svc file that is referenced is using pretty much the same pattern. It is calling an internal client over net.tcp. The call is wrapped in a try/catch
try
{
var client = new InternalServiceClient();
var response = client.GetActiveVerification(request);
client.Close();
return response;
}
catch (FaultException fe)
{
LogError(MethodBase.GetCurrentMethod().Name, fe);
throw;
}
Here is my problem, how do I get errors here to bubble up to my UI catch statement? When I leave it like this, I get an unhandled exception error from visual studio. I have tried removing the throw which makes me specify a return value, and I return null. This makes the UI not work correctly. I have tried throw new Exception(fe.message) and I get the same problem with the unhandled exception. Basically my question is how can I accomplish what I need? What am I missing?
You need a separate try/catch block around your try/catch block. You have it such that you will catch a FaultException and any type of Exception, but your Exception block will not catch your throw from FaultException. So, just enclose this with another try/catch or handle it within both the FaultException catch and the Exception catch.
The reason could be the throwing of another exception in your second code snippet that isn't of the type FaultException; such an exception would pass as unhandled in this situation. Maybe you should add another catch block to your second code snippet that catches exceptions of the type Exception:
catch (FaultException fe)
{
LogError(MethodBase.GetCurrentMethod().Name, fe);
throw;
}
catch (Exception ex)
{
throw;
}
Is the FaultException you are re-throwing a generic type? Are the relevant classes detailed by any FaultContract attributes accessible to all assemblies in this execution stack?
Edit: In your first code snippet ...
catch (FaultException ex)
{
LogError(ex, MethodBase.GetCurrentMethod().Name);
throw;
}
If the unhandled error occurs on the throw statement of this handler, then #MCain is right.
I believe you have to throw in the catch block for the error to bubble up
try
{
}
catch (SqlException _SqlException)
{
//Log Error to file
throw;
}
catch (IOException _IOexception)
{
//Log Error to file
throw;
}
catch (Exception _exception)
{
//Log Error to file
throw;
}
This kind of a block will be in the calling method