IDE = VS7 or 2002
Hi all, I have a really weird problem here. The code doesn't appear to be executing as expected. I'm running this through the debugger and it's performing really strangely.
I have made sure that the Virtual Directory is using ASP.NET 1.0.3705.
The code follows and I explain what the debugger shows me as the execution steps in the comments:
try
{
objConnection.Open(); // STARTS HERE
objCommand.ExecuteNonQuery(); // DOES NOT THROW EXCEPTION
int c = 0; // THIS LINE IS EXECUTED
}
catch (SqlException sqle)
{
LogError(); // THIS LINE IS NOT EXECUTED
throw sqle; // THIS LINE IS EXECUTED AFTER THE int c = 0;
// sqle IS NULL
// EXCEPTION IS NOT CAUGHT AND
// EXECUTION CONTINUES IN FINALLY BLOCK
}
finally
{
// EXECUTES AS EXPECTED FROM HERE ON OUT,
// AS THOUGH THE throw sqle; DID NOT HAPPEN.
if (objConnection.State == ConnectionState.Open) objConnection.Close();
}
Has anyone experienced this strange behaviour before? Any idea how to fix it? I may change the method extensively, but I'd still like to know why this is happening.
I suspect since the sqle is null that is why the throw does not behave as expected. But why did we jump into this code block in the first place?
I have reloaded it several times, saved and rebuilt, and executed with the debugger and watched this behaviour multiple times.
Thank you all for your help!
All the best,
Graham
Very strange. I'm not sure what's going on with your code, but one thing I saw is the use of:
catch (SqlException sqle)
{
LogError(); // THIS LINE IS NOT EXECUTED
throw sqle; // THIS LINE IS EXECUTED AFTER THE int c = 0;
// sqle IS NULL
// EXCEPTION IS NOT CAUGHT AND
// EXECUTION CONTINUES IN FINALLY BLOCK
}
You want to write:
catch (SqlException sqle)
{
LogError();
throw;
}
To re-throw the exception.
Wait.. your code doesn't throw an exception and you're wondering why it doesn't execute the catch block?
EDIT (referencing your comment):
That sounds really hard to believe. I never heard of a case where the actual exception inside the catch block was null and as you already mentioned did the first line inside the catch block not execute which in my opinion points into the direction that there was no exception at all.
Did you try to check the program flow by using old-fashioned debugging techniques (Debug.WriteLine) and skipping the debugger?
My assumption is that you're looking at the wrong place where the exception is thrown.. or there's no exception at all.
Related
In other words, how are these two different?
try
{
// Something that can throw an error
}
catch
{
// Handle the error
}
finally
{
// Something that runs after the try statement
}
vs.
try
{
// Something that can throw an error
}
catch
{
// Handle the error
}
// Something that runs after the try statement
finally block always executes.
You can be sure, that this block will be executed no matter what.
Literally it is something like:
Try something, catch some exceptions(if told to and if they are there) and execute the
finally block finally.
If there is a break in the try block or an exception, it may cause the program to halt. In cases like these code that is mandarory to be executed, like closing open connections and returning items to the connection pools are writen in the finally block. The finally block ensures that the code written inside it will be executed.
If you only ever use general catches (i.e. catch without args or catch(Exception ex)), whether to put code in finally or after try/catch is basically a stylistic choice, as both a finally block and code after a try/catch will execute in any situation (barring deliberate escape mechanisms such as return).
However, if you use a narrow catch, and the exception isn't caught, what will happen is the finally block will still execute, however the code after the try/catch won't.
I saw a similar question here, but there are still some things I don't understand. As far as I know when you use try-catch block, if an exception is thrown the catch block will be executed right after and no code after the catch clause in the same code block will be executed. So if I get it right if we have:
try
{
// do something
// throw an exception for some reason
}
catch (Exceptiox ex)
{
// do something when there is and exception thrown
}
// some code that will never be runned if and exception was thrown above
I'm not 100% sure that the catch stops further execution outside its scope but this is one of my questions so correct me if I'm wrong.
So what's the point of using return in a catch block if you don't need to return any value at all? I see this in some methods from inherited code I'm working on. For example:
public void DeleteImage(AppConfig imageInfo, string imageName)
{
string imgPath = imageInfo.ConfigValue.ToString();
try
{
File.Delete(imgPath + "\\" + imageName);
}
catch (Exception ex)
{
logger.Error(ex.ToString());
return;
}
}
Here there is no need to do anything besides logging the error. Why then use return. Is it a mistake? Won't the method finish if you don't return explicitly? If there was more code after the catch clause would it be executed if the return wasn't there and the catch was used only for logging the error?
I'm not 100% sure that the catch stops further execution outside it's
scope but this is one of my questions so correct me if I'm wrong.
No, that's incorrect. Execution will continue normally after the catch block, unless some code inside the block changes the flow (e.g. throw or return).
Therefore return is necessary if you don't want execution to continue. Even if there is currently no code after the catch block, IMHO it's OK to make it more explicit that "handling this type of exception involves not executing any code after this point".
That said, you should be wary of catch (Exception ex) -- catching all types of exception should always be questioned and is almost always not quite the right thing to do (although in this case it's for logging, which is an "allowed exception to the rule").
I'm not 100% sure that the catch stops further execution outside it's scope but this is one of my questions so correct me if I'm wrong.
No, it doesn't. If the catch block doesn't either rethrow or return, execution will continue from the end of the try/catch statement.
In the sample you've given, the return statement is pointless. If there were code after the catch block, that would be a different matter, as the return statement would make the method return immediately.
It's not a mistake to have a return statement in a catch block like that, in that it's perfectly valid code, and will presumably still execute as intended - but it's definitely odd. It could well be that it was cut/paste from a method where the return statement was important.
(It's also almost always a bad idea to catch Exception, but that's a different matter.)
If there would be no return statement and further any code instead of that, then that code would have got executed. And you are allowed to return any thing from catch block. There is no restrictions for it.
What is the difference between 2 conditions? Every time when method1 or method2 runs, there should be a code block that is required to run. It seems to me that 2 method are the same.
// example method1
void Method1(void)
{
try
{
// do something
}
catch (Exception ex)
{
// do something
}
finally
{
// do something whenever method1 runs
}
}
// example method2
void Method2(void)
{
try
{
// do something
}
catch (Exception ex)
{
// do something
}
// do something whenever method2 runs
}
Finally block seems to be unnecessary for me.
In your first example, you could re-throw the exception and the code inside the finally would still run. This would not be possible in the second example.
If you choose not to re-throw the exception, then yes there is little difference. However, this is considered bad form - very rarely should you need to consume an exception that you cannot explicitly handle.
It is a keyword to help you with code execution flow. When you throw an exception the execution flow of the code is affected (like using return), the finally keyword allows you to express that when an exception occurs (or you return from a try) you still want execution to do something as it's leaving.
To answer the question facetiously, it is a must when you need it and not when you don't.
Further Reading
To be on the safe side, before you attempt to start making use of this keyword, please read the documentation for it:
http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
And the exception handling keywords in general:
http://msdn.microsoft.com/en-us/library/s7fekhdy.aspx
Examples
Catch an exception to do something with it, then re-throw it. Use finally to call any tidy-up code:
try
{
OpenConnectionToDatabase();
// something likely to fail
}
catch (Exception ex)
{
Log(ex);
throw;
// throw ex; // also works but behaves differently
}
// Not specifying an exception parameter also works, but you don't get exception details.
//catch (Exception)
//{
// Log("Something went wrong);
// throw;
//}
finally
{
CloseConnectionToDatabase();
}
Don't register any interest in catching exceptions, but use finally to tidy-up code:
try
{
OpenConnectionToDatabase();
// something likely to fail
}
finally
{
CloseConnectionToDatabase();
}
Return from your try because it looks nicely formatted, but still use finally to tidy-up code:
try
{
OpenConnectionToDatabase();
return 42;
}
finally
{
CloseConnectionToDatabase();
}
As you know the code written inside the finally block always runs.
Please have a look onto the following point written below, it will clear your all confusion.
Finally is used for Resource management. Mainly for releasing an resources. It always runs independent upon the Exception.
As we know catch is used for handle an exception, but sometimes it fails to handle to an External exception. Then the finally block is used to handle that exception to perform the operation.
The code in the finally block will run anyway after the try-catch, it is very usefull for clean up.
try
{
// open resources
}
catch (Exception ex)
{
// something bad happened
}
finally
{
// close resources that are still opened
}
This will behave very differently depending on whether you return from the try, for example. Also - the finally will run even if the catch throws an exception (or re-throws the original exception), which will not happen without the finally.
So: it isn't required, but it will behave differently. So if you want the code to happen, put it in the finally.
In many ways, try/finally is much more common than try/catch or try/catch/finally.
You do not absolutely have to have the finally block, however, having it guarantees that the code within it will always run (unless there is an exception in the finally!).
Consider the following:
void Method2(void)
{
try
{
// do something
}
catch (Exception ex)
{
// do something
throw;
}
// do something whenever method2 runs
}
the code after the try/catch will not execute if an exception is thrown. Additionally, if the code within the catch block has an error that causes an exception (such as your logging throwing an unexpected exception) the code that should have been in the finally will not run, leaving and cleanup undone.
Also a return statement will cause that code to not be run, while the finally will still be executed (also, here you can see that the catch can be skipped too, allowing any exceptions to propogate upwards - AFTER executing the finally):
void Method2(void)
{
try
{
// do something
return
}
finally
{
// do something whenever method2 runs
}
}
Whenever you have cleanup code that must be run at the end of a method, use finally (or if your objects implement IDisposable use the using statement).
The finally block ensures that any code within it ALWAYS gets executed so if you have a return statement inside your try block or rethrow an exception within your catch block, the code inside the finally block will always execute.
It is a must if you need to ensure that something happens regardless (e.g. disposing of a resource etc)
The big difference is that try...catch will swallow the exception, hiding the fact that an error occurred. try..finally will run your cleanup code and then the exception will keep going, to be handled by something that knows what to do with it.
i got this exception when i done the code given below..
"Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack."
--code--
try
{
if (retVal == 0)
Response.Redirect("Success.aspx");
}
catch(Exception error)
{
Response.Redirect("errorpage.aspx");
}
finally{
}
from searching in net i found it to be a bug and if its success then we should end response... ie " Response.Redirect("Success.aspx", false); ".it works fine.. is this a good method or there is any other efficient method to handle this exception please help....
Are you sure that it's an Exception? What type of exception is it?
It looks more like you have used 'Break' in the debugger and it cannot evaluate a watch or expression because it's busy running a line of code or non-managed call.
Try pressing F10 or F11 to step to the next line of managed code then looking at the expression again.
Using a breakpoint should also work.
If that doesn't solve it, please post a comment and I will try to respond or be more specific.
This is probably what you are seeing:
Also, Response.Redirect will always throw a ThreadAbortException, see here:
http://msdn.microsoft.com/en-us/library/a8wa7sdt(VS.80).aspx
To ensure that no more code gets executed, and the next code that will be run is in the context of generating the next page.
You could do this instead:
try
{
// code with Response.Redirect
}
catch (ThreadAbortException)
{
// ignore this exception, it is expected from Response.Redirect
}
catch (Exception ex)
{
// handle / log / redirect using ex
}
Hope that helps!
try
{
list = from XElement e in d.Descendants(wix + "File")
where e.Attribute("Name").Value.Contains(temp.Name) &&
e.Parent.Parent.Attribute("Name").Value.Contains(temp.Directory.Name)
select e;
}
catch (NullReferenceException e)
{
MessageBox.Show(e.Message);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
now my question is why does this code produce a run time error saying I have a NullReferenceException unhandled. If you need more information about the program let me know.
EDIT:
The debugger points to the "where" part of the linq statement. When I run this program direct from the exe file I still get the exception.
EDIT: Okay, I think I know the problem... it's due to deferred query execution.
If you've just got the query construction in the try/catch block, that's not going to catch exceptions which occur while the query is being executed.
Look at the stack trace you've got, and you'll find that there'll be a stack frame where you're executing the query - it's just the auto-generated lambda expression which comes from this bit of code, and it's not running within the scope of the try/catch block.
ORIGINAL ANSWER:
Are you just seeing the exception in the debugger? If so, go into the debugger exception dialog and change the preferences for the point at which exceptions cause the debugger to "break". The catch block should be handling the NullReferenceException normally. (Admittedly I don't think you should really be catching NullReferenceException in the first place, and catching all exceptions like that is generally a bad idea too, other than at the top of the stack - but that's a different matter.)