The code is intentionally written to throw a NullReferenceException, where the main list is initialised but the sub-lists inside the main list are not initialised.
Code is as follows:
List<List<string>> myList01 = new List<List<string>>(new List<string>[3]);
string[] myFruits = new string[3] { "apple", "banana", "citron" };
try
{ myList01[0].Add(myFruits[0]); }
catch (NullReferenceException e)
{ Console.WriteLine(e.Message); }
NullReferenceException was thrown, but not caught by the catch block, as shown below
Why is this happening? How to let the catch block catch this exception?
No, the exception is not caught in this case
Well, it would be caught if the code had progressed as far as handling the throw, but it hasn't yet. It will if you press F10 etc
It's breaking as soon as the exception is thrown because you've told VS to break when it's thrown:
Nominating an exception for "Break When Thrown" means as soon as it happens, VS stops what it's doing and opens the exception helper. It doesn't run any catch handler or anything. It literally stops immediately to tell you. If you then step/run the code you'll see control jump to the catch..
#Chandana System.NullReferenceException is ticked in the Exception Settings.
It needs to be unticked - these are the settings for "Break When Thrown" which is different to "Break When Unhandled" (i.e. an exception occurs and there is nowhere a catch that will deal with it)
When you're running with it ticked you'll see:
If you press F10, VS jumps to the handler and the wording changes:
Related
I have the following code:
protected void ExecuteInTransaction(Action action)
{
using (SQLiteTransaction transaction = connection.BeginTransaction())
{
try
{
action.Invoke();
transaction.Commit();
}
catch(Exception)
{
transaction.Rollback();
throw;
}
}
}
While testing this class, I managed to throw an exception in order to test the catch branch.
As I'm in Debug mode, I continue the execution of this throwing, to see how the calling class handles it, but the exception is never thrown by the method, instead, it's like the exception is constantly being thrown and caught, thrown and caught all over again, never exiting the function.
In Release mode, the application freezes and stops working:
Does anybody know why this is happening, and how can I avoid it?
Thanks in advance!
There is no infinite loop.
Visual Studio just stops at the place where the uncaught exception would abort the program.
Trying to continue does nothing because there is nothing further to execute (VS just displays the same message again to remind you of that).
If you had a try/catch handler in some calling function, you would be able to debug into there.
(But if that catch handler rethrows again, VS would stop there, too.)
Please note that SQLiteTransaction automatically handles rolling back when an open transaction is disposed; it is designed so that your code can be simpler:
protected void ExecuteInTransaction(Action action)
{
using (var transaction = connection.BeginTransaction())
{
action.Invoke();
transaction.Commit();
}
}
Are you sure there's a catch up the stack that can handle this error? The dialog you showed is what you see when an Exception goes unhandled off the top of your program's Main method. The debugger message actually tells you that it was unhandled, so there is no next statement to step to.
Does anybody know why this is happening, and how can I avoid it?
Its hard to say without seeing your call stack.
In general there are 3 possible options:
The exception is being caught higher up the stack.
There's a kernal mode system call somewhere in your call stack and the exception gets swallowed. This only happens when running a 32 bit application on 64 bit windows. The most notable example being an exception thrown in the OnLoad() method of a Form. See VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows for more info.
The exception is being thrown on a ThreadPool thread and not being propagated back to the main thread.
Take the throw; code out of the catch block. If you want to know when the code goes into the catch block then use a breakpoint or Debug.WriteLine().
The catch block of a try/catch doesn't not catch exceptions thrown in itself. So the throw; code is creating an unhandled exception. If you want to test the code that's in the catch block then add the throw; code to the end of the try block.
EDIT:
I didn't realize OP wanted the exception to propogate up the chain. He mentioned nothing about the exception being propagated up the chain and his code shows no support for an exception that propagates up since he doesn't show the code that calls this ExecuteInTransaction(Action) method. A catch block can rethrow the exception that it catches. I agree with that. However the code catch(Exception){ throw; } will not re-enter the same catch block. If it would that would create an infinite loop and that's not what happens. If there is a try/catch block surrounding this then the outer catch block will catch the rethrown exception however his code only includes a single catch block. Therefore when it tries to rethrow the exception there is nothing to catch it and the application breaks.
Try something like this:
private void Main()
{
// Instantiate action variable. I know this wouldn't work, but it's just for show.
Action myAction;
try
{
ExecuteInTransaction(myAction);
}
catch(Exception ex)
{
Debug.WriteLine("Error happened and transaction rolled back. " + ex.Message);
}
}
protected void ExecuteInTransaction(Action action)
{
using (SQLiteTransaction transaction = connection.BeginTransaction())
{
try
{
action.Invoke();
transaction.Commit();
}
catch(Exception ex)
{
transaction.Rollback();
throw ex;
}
}
}
This question already has answers here:
Visual Studio: How to break on handled exceptions?
(8 answers)
Closed 8 years ago.
If I run the code below that calls Test1(), VS2012 will break nicely at that line and show me exactly what's going on. If I comment out Test1 and put in Test2, then the try catch does not stop on the line, it just logs it out to the console.
How can I get VS2012 to stop on the error line, even when it is surrounded by a try catch statement?
private void Button_Click(object sender, RoutedEventArgs e)
{
//Test1(); // No try catch - stops on error line dividing by zero.
Test2(); // Try catch - Just writes out to console.
}
private void MakeError()
{
int i = -1;
i += 1;
int j = 1 / i;
Console.WriteLine(j.ToString());
}
void Test1()
{
Console.WriteLine("MakeError in Test1");
MakeError();
}
void Test2()
{
Console.WriteLine("MakeError in Test2");
try
{
MakeError();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
While the other answers are correct, this is the intentional behavior by default, you can tell Visual Studio to alert you to those exceptions if you wish.
How to: Break When an Exception is Thrown:
On the Debug menu, click Exceptions.
In the Exceptions dialog box, select Thrown for an entire category of exceptions, for example, Common Language Runtime Exceptions.
-or-
Expand the node for a category of exceptions, for example, Common Language Runtime Exceptions, and select Thrown for a specific exception within that category.
What you want is Visual Studio break execution when an exception is thrown:
On the Debug menu, click Exceptions.
In the Exceptions dialog box, select Thrown for an entire category of exceptions, for example (your case), Common Language Runtime Exceptions.
MSDN Reference.
Visual Studio will only intervene when there is an unhandled exception , in this case a division by 0. The try...catch handled the exception. Since there is no exception left unhandled, Visual Studio will not jump out.
try and catch statements are intended so that the flow of execution can still happen, even when an exception occurs. The debugger only stops when the exception is unhandled, which the try catch does.
This is intentional.
I saw some code the other day in one of our projects that uses a try catch and re-throws the caught exception like this:
try
{
exceptionProneCode();
}
catch(Exception ex)
{
throw ex;
}
Nothing else was done with the exception in the catch block so I'm not even sure why it's re-thrown. I can't see any benefit to actually throwing the same exception again and doing nothing with the exception.
If you re-throw an exception that's caught in the catch block, how does C# handle this? Does it get stuck in an infinite throw/catch loop? Or does it eventually leave the try catch?
Consider these two models:
1- By re-throwing ex:
catch(Exception ex)
{
throw ex;
}
you loose StackTrace. If the exception is logged somewhere the StackTrace containing immediate frames of the call stack (history of method calls) is lost.
2- In contrast by throw:
catch(Exception ex)
{
// do something here
throw;
}
you maintain StackTrace. You can do additional processing and then re-throw the exception without loosing the trace string.
It continues to throw the exception up the calls stack. One thing that this piece of code does that is different from if you didn't catch the exception, it will reset the exception location (call stacks, line #, etc) to where you re-threw the exception, so you won't have the location where the original exception was thrown.
If you're not going to actually do something in the catch block I would recommend not catching, or at the very least rethrowing with just a throw instead of throw ex.
It throws the exception to the caller. But it handles it here so it doesn't throw an unhandled exception. However, honestly, I don't see the benefit of this. Just let it throw the exception. Why? Because an exception is only unhandled if the entire call stack above it doesn't have a try ... catch. This isn't doing anything useful.
Does it get stuck in an infinite throw/catch
loop? Or does it eventually leave the try catch?
No. Yes.
The code provides no benefit and does harm to debugging as noted by everyone else.
A good catch block will catch a specific expected issue and log & continue (the problem doesn't indicate the applications state is corrupt), log and halt (because the application is now in an unknown state and continuing could wreck more harm), do something else (e.g. fall back to an equivalent technology/algorithm), wait and try again.
The default is that something is unexpected, should be logged and the application should be stopped-- either abandoning the page or if a winforms app, revert back to a known state if possible.
See below for an explanation of what is going on
I have a really weird issue where the exception caught is null.
The code uses MEF and tries hard to report composition errors. Using the debugger I can see the exception being thrown (an InvalidOperationException) but when it is caught by the last catch block in the code below the ex variable is null. This is true both in the debugger and when executing the code normally.
static T ResolveWithErrorHandling<T>() where T : class
{
try
{
IocContainer.Compose(Settings.Default.IocConfiguration);
return IocContainer.Resolve<T>();
}
catch (ReflectionTypeLoadException ex)
{
// ... special error reporting for ReflectionTypeLoadException
}
catch (Exception ex)
{
// ex is null - that should not be possible!
// ... general error reporting for other exception types
}
return null;
}
The code I have replaced with comments is really simple code to format the error message. Nothing strange going on there.
I have tried to alter the code to discover what effect that might have:
If I remove the first catch block (ReflectionTypeLoadException) the exception caught in the final catch block is no longer null.
If I catch another exception type in the first catch block the exception caught in the final catch block is no longer null.
If I add a catch block for InvalidOperationException as the first catch block the exception caught in that block is not null.
If I add a catch block for InvalidOperationException between the two catch blocks the exception caught in that block is null.
The project uses Code Contracts and the code generated by the compiler is post-processed to check the contracts. Unfortunately, I havn't figured out a way to get rid of this for testing purposes without performing major surgery on the project.
My current workaround is to not catch ReflectionTypeLoadException and instead branch on the type of ex in the general exception handler.
What could be the explanation for this "impossible" behavior? What is up with ReflectionTypeLoadException catch block?
Embarrassingly the exception is not null and it cannot be null per the C# standard 15.9.5.
However, using Code Contracts in a project can mess up the display of local variables in the debugger because the IL code generated by the compiler can be rewritten by Code Contracts so the final IL is slightly out of sync with the debug information. In my case the ex variable is displayed as null even it is not. The unfortunate nature of the error reporting taking place right before application termination meant that I believed the error reporting to not be called as a result of ex being null and ex.Message throwing a NullReferenceException inside my catch block. Using the debugger I was able to "verify" that ex was null, except it was actually not null.
My confusion was compounded by the fact that a catch block for ReflectionTypeLoadException seems to affect the debugger display issue.
Thanks to all who responded.
Just ran into this same problem. I finally found out that I catched different exceptions with the same name, like you did:
catch (ReflectionTypeLoadException ex)
{
// ...
}
catch (Exception ex)
{
// ex is not null!
// ...
}
Both are named 'ex'. Changing one of both names solved this problem for me, like:
catch (ReflectionTypeLoadException reflectionEx)
{
// ...
}
catch (Exception ex)
{
// ex is null - that should not be possible!
// ...
}
I ran in the same problem. In my case renaming the exception variable (e.g. ex => ex1) allowed to me to catch any exception...
You should check if at some point, the IocContainer catches an Exception ex throws ex.InnerException without checking if it is null.
C# happily accepts throw null, and ends up in catch (Exception).
I ran into the same problem. The exception was null when viewed in the debugger even though the correct type of exception - UpdateException - was being caught. I could view the exception by opening the Exception Assistant.
As soon as I turned off "Perform Runtime Contract Checking" caught exceptions where no longer null. I have been actively using code contracts for going on a year now and had not seen this problem before I starting working with EF 4.1 in this particular project recently - but I do not know if EF was a controlling variable in regards to caught exceptions being null.
The exception is in fact not null, it's a problem with the debugger.
Code contracts (ccrewrite) changes IL opcodes and that perturbates the debugger, because leave.s opcodes are transformed into leave opcodes.
The two opcodes have different sizes and instruction adresses change, that's why the debugger is lost when exception names are the same.
You can use $exception in the debugger to workaround the issue.
I have got the same situation, too. It happened to be a bug of Eclipse debugger. (Really, this situation can be only the result of some debugger's bug. )
Eclipse restart was enough - runtime exception becomes normal, not null. Other debuggers could be not so kind.
Will both catch blocks be hit?
try
{
DoSomething();
}
catch (AuthenticationException e)
{
throw;
}
catch (Exception e)
{
throw new AuthenticationException("Hello ");
}
It's valid (in that it will compile, build and run), but it's not good practice.
Catching the general exception only to rethrow a specific exception will cause problems. If nothing else you are destroying the original exception call stack.
In response to your edit, both catch blocks won't be hit.
If AuthenticationException is raised the first block will be executed, for any other exception the second block will be executed.
Only one exception block will be hit. And they go in order, so if DoSomething() throws an AuthenticationException, the first catch block will run.
That said, I'd probably not use try/catches here at all if all you're doing is rethrowing the exceptions. This is not a good practice. At the very least, make sure you add the original exception in your second catch as the InnerException of the AuthenticationException you're creating:
catch(Exception e)
{
throw new AuthenticationException(e.Message, e);
}
This code will throw an AutheniticationException if DoSomething throws anything. It will be the same exception if DoSomething throws AuthenticationException, or a new exception in any other case.
A side note - its not really good practise:
You loose all details of an exception which is not AuthenticationException
Why would you throw an AuthenticationException here, if the underlying code thinks there is something else wrong? A code smell for me.
Yes if you have different kinds of exceptions. (2 exceptions)
No if you wish that the first block will arrive in the second. (1 exception)
No. Both catch blocks will not be hit.
If DoSomething throws an AuthenticationException, then it will be caught and rethrown.
If DoSomething throws any other exception, a new AuthenticationException will be thrown with the message "Hello".
If DoSomething() throws an AuthenticationException then
catch (AuthenticationException e)
will be used. For all other types of exceptions,
catch (Exception e)
But you shouldn't throw a new AuthenticationException inside the second catch.
The second block will not catch the rethrown exception from the first block.
One benefit I can see for catching and rethrowing an exception would be to convey the message, "The requested operation did not succeed, but the system state is essentially as it was before the operation was attempted." While catching all exceptions in an inner routine and hoping that none of them represent a problem which should cause the main program to terminate is somewhat icky, I'm not sure what alternative design is better. One could litter the code with:
If Not Integer.TryParse(inputString, inputVar) Then
Throw New MyApp.FileLoadException("Whatever")
EndIf
but it really seems more natural to just use Integer.Parse and catch any exception that occurs. Catching and recasting general exceptions within a small domain where their expected causes are known is far less evil than swallowing general exceptions at a higher level.