We have following code:
try
{
// some code throwing MyException
}
catch (MyException ex)
{
// [1]
// no (re)throw here
}
catch (Exception ex)
{
if (ex is MyException)
{
// [2]
}
}
If we run the code without a debugger attached, everything runs fine. However, if we debug the code, we don't get to point [1] but [2]. As far as I understand the language specification this should not be possible.
Even weirder, this code used to run fine even while debugging. The strange behavior started only a few days ago.
Depending on original sources, it may be related to this issue : Why can't I catch a generic exception in C#?
Check that you have done a full rebuild and are using the correct pdb files. Also check that you don't have some conditionally compiled code changing things (i.e. code between #if DEBUG statements).
Related
Our Application is moving some files it requires to run during startup.
The application takes care (on shutdown) to properly stop every process using this files.
However, if the application crashes / or you just hit "stop" in VS on Debugging - some executables might still be running.
So, if you quickly restart the application, it might happen, that the copy-attempt is failing, due to the file is still in use.
For such a case, we just ignore the failed copy attempt - or more exactly: the failed deletion attempt which should make sure, that the latest version is available:
foreach(String entry in contents)
{
if (System.IO.File.Exists(entry))
{
try
{
System.IO.File.Delete(entry);
}catch (Exception e)
{
//ignore during this startup.
}
}
}
Now, this works perfectly fine, as there is a version of the file available for usage and the production version just ignores the exception.
The annoying Problem is, that the Debugger "breaks" everytime, this error happens.
We don't want to generally "ignore" any System.IO.IOException thrown while debugging.
We tried to annotate the method in Question with [System.Diagnostics.DebuggerStepThrough()] which works, but causes the exception to be catched at the callers position.
So, is there a way to ignore "some" exceptions raised at a certain line of code, even if general "breaking" for that kind is enabled?
Some #if (DEBUG)-Directives which will avoid the exception to be catched at this particular line of code?
Something like:
foreach(String entry in contents)
{
if (System.IO.File.Exists(entry))
{
try
{
#if (DEBUG:NoThrow)
System.IO.File.Delete(entry);
#endif
}catch (Exception e)
{
//ignore during this startup.
}
}
}
I'm still interested in an answer, cause it has "many" usecases.
For the time beeing, we used the following "workaround": Check, if the file has been accessed withing 3 minutes - then don't attempt to delete it.
(For DEBUG-Mode!)
Remember, the actual issue is only about the "debugger", not production, where Exceptions can be caught (and ignored) easily for a certain line of code.
We just want to avoid "Debugger-Breaks" kicking in if the exception can savely be ignored AT THIS line of code.
foreach (String entry in contents)
{
if (System.IO.File.Exists(entry))
{
try {
#if (DEBUG)
FileInfo fi = new FileInfo(entry);
if (fi.LastAccessTime < DateTime.Now.AddMinutes(-3))
{
#endif
System.IO.File.Delete(entry);
#if (DEBUG)
}
#endif
}
catch (Exception e)
{
//ignore
}
}
}
This is NOT a solution, it's a workaround, reducing the Debugger-Breaks at this line of code by about 99%, in case you just "Stop" Debuggin within Visual Studio!
C# .Net 4.6.1
I am using a 3rd party library. When iterating through its object, my program blows up because the property i'm accessing from the library has thrown an exception.
So when my program gets to this line of code, the exception is thrown:
case CellType.Formula:
{
cNew.CellFormula = "IFERROR(FF3 / EY3,\"\")";
cNew.SetCellFormula(cOld.CellFormula); //this is where it blows up
break;
}
When debugging the code, I can see the exception has been thrown. The image above shows this. So, I know something has gone wrong in the library property and what I want to do is capture this error BEFORE hitting the line of code using the property and keep going along with the application.
Is there a way to check an object for exceptions and tell my code to skip over it or do whatever? For example:
if (cOld.CellFormula == Exception){
// do something
}
Thanks
On the breaking line
cNew.SetCellFormula(cOld.CellFormula);
You can put a try catch around it, like so
try
{
cNew.SetCellFormula(cOld.CellFormula);
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
this will display a message box with the error text in it
If you are running this as a console application replace
MessageBox.Show(e.Message);
With
Console.WriteLine(e.Message);
That will write the message to the screen (remember to take it out in production!)
I have a class Dispatcher with a method Send as follows:
public class Dispatcher : IDispatcher {
public void Send(Order order) {
Type type = typeof(IOrderHandler<>).MakeGenericType(order.GetType());
IOrderHandler handler = (IOrderHandler)ObjectFactory.GetInstance(type);
try {
handler.Handle(order);
} catch (Exception exception) {
ILogger logger = ObjectFactory.GetInstance<ILogger>();
logger.Send(exception);
}
}
} // Send
I am handling orders and catching exceptions ...
When I am debugging I would like to still fire the exception.
How can I do this?
Thank You,
Miguel
Just add this line to your catch block:
if (System.Diagnostics.Debugger.IsAttached) throw;
You can add the following in your catch block:
#if DEBUG
throw;
#endif
So your code would look like:
try
{
handler.Handle(order);
}
catch (Exception exception)
{
ILogger logger = ObjectFactory.GetInstance<ILogger>();
logger.Send(exception);
#if DEBUG
throw;
#endif
}
If you want the exception notification in IDE during debugging in Release configuration, then use #Hans Passant's answer, because that will let you know about the exception for both Release and Debug configuration.
Well, based on the fact that you'd like the exception to still be thrown, but only when debugging, you could do this:
Open the Debug menu and choose Exceptions.
When the dialog loads, tick the check box next to Common Language Runtime Exceptions under the Thrown heading.
This will cause you to get a first chance exception. What that means is you'll be notified by the IDE, when debugging, and you'll get a chance to handle it before processing continues. This will actually let you see it before it even gets logged.
What's more, you can actually unselect exceptions you don't want with this approach because they are broken down by exception type underneath the Common Language Runtime Exceptions grouping.
More detail...
Go to Debug > Exception and check the CLR exceptions for "thrown", this will take you right there. alternatively place a breakpoint on the catch block.
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.
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.