postsharp aspects result in exception being thrown at "end" of method - c#

I am using PostSharp in C#, for using AOP in my codebase. Recently i've noticed that errors are not being thrown where they are actually thrown, but at the end of the method which was weaved with any aspect. For example, take the sample code below:
public void methodUsingAspects()
{
doSomething1();
doSomethingWhichThrowsError(); //an error is thrown in this method
doSomething2();
} //in visual studio, while debugging, the debugger stops at this line (end of method), not at the actual line the error got thrown.
The error gets shown as if thrown where there is the last curly bracket }. This is quite frustrating especially when the error is thrown quite deep inside the calls the method does.
I can assume why this is done, since the code is changed - but is it possible to somehow leave it work as it was before?

Related

How to prevent Visual Studio from breaking on all the awaits after it breaks on a deeper level Exception

So what happens is this:
Visual Studio breaks on (for me, as an end-user) valid Exception five async/await methods deep.
This is behaviour that I like, because I can inspect state and see what is going on.
Usually this line is marked yellow.
When I press continue it will break again on every async/await in the upper stack. Marked as green, probably because the real stack is underneath, but that is my assumption.
These last ones I want to prevent, as this means I have to press 5 times F5 to continue, while not giving me more information then I could have figured out by break 1.
Is there any way to prevent 4 without disabling 1?
Note: this is an ASP.NET MVC application and this can be i.e. a background Ajax call.
It looks you are not catching the exception, and then it will bubble up through the call stack, regardless if you inspected it using the debugger or not. This is by design. There is no way to clear an exception that already occurred. The call stack is already in state of unwinding, and that is irreversible.
A solution might be to add a try catch with a conditional throw, like this:
try
{
// code that may crash
}
catch
{
// inspect the Exception here using VS
var reThrow = true; // You can change reThrow to false while debugging
if (reThrow) throw;
}

Strange debugger behaviour in async method

When I stepped over breakpoints in my code I have encountered strange behaviour of debugger:
public async Task DoSomeWork()
{
await Task.Run(() => { Thread.Sleep(1000); });
var test = false;
if (test)
{
throw new Exception("Im in IF body!");
}
}
Debugger goes into if body. It's remarkable that the exception is not really thrown but just looks like it is. So you can't reproduce that if you place breakpoint right on throw. You must place it above and step down to the if body to catch it. The same works on any kind of exception instance (as well as explicit null) and even on return instead of throw.
Besides that it works even if I remove line with await.
I tried to run this code snippet from different PCs so its not a PC trouble. Also I have thought it is bug in VS code and tried to run it in Rider from JetBrains - the same result.
I'm sure it's the async thing but how it explicitly works?
Your code reproduces the issue easily, in a "Debug" build, using Visual Studio 2015. I had only to add in Program.Main(), with a call to DoSomeWork().Wait();, set a breakpoint in the method and step through it.
As for why it happens, this is undoubtedly due to the combination of the async method being rewritten and the debugging database (.pdb) generated. Similar to iterator methods, adding async to the method causes the compiler to change your method into a state machine. The actual IL that's generated looks only a little bit like the original method. That is, if you look at it, you can identify the key components of the original code, but it's now in a big switch statement that handles what happens as the method returns at each await statement, and then is re-entered with the completion of each awaited expression.
When the program statement appears to be on the throw, it's really at the implicit return statement in the method. It's just that the debugging database for the executable doesn't provide a program statement for that line.
There's a hint, when debugging, that that's what's happening. When you step over the if statement, you'll notice it goes straight to the throw statement. If the if statement block were really being entered, the next program statement line would actually be the opening brace for the block, not the program statement.
You can also add e.g. a Console.WriteLine() at the end of the method, and that will give the debugger enough information to sync up and not show you at the wrong line number.
For additional information on how async methods are handled by the compiler, see Is the new C# async feature implemented strictly in the compiler, and the links provided there (including Jon's series of articles on the topic).

Null Reference Exception in Visual Studio Debugging

I am trying to test some code and now visual studio is throwing a null reference exception on the following line:
List<int> liveIds = new List<int>();
I am starting to think that visual studio has old code that it is looking at because no matter how I have tried to declare this line it continues to throw a null reference exception on this line.
Anyone know something that I might be missing?
UPDATE:
ok so I changed out the variable and now I can't get the same error to happen on the previous line. Now it is happening on this line.
Ok so after some testing, things worked once I refactored the code and extracted the following code to a new method:
// remove hospitals that are not currently assigned to someone
hospitalsToCheck.RemoveAll(
h =>
{
return
!currentAssignments.Exists(
a => a.AssignmentGroup.AssignedUnitIds.Intersect(h.Units.Select(u => u.UnitId)).Any());
});
It seems that when I had code that was manipulating the list in the same method that it was defined, that is when I was getting the null reference exception.
Maybe the debugger itself is producing the exception.
I got a very similar situation, where i'm assigning a value from a function and the exception occurs right after executing the function (the Locals window indicates that the function does return a value):
var xmlElement = Serialize(data);
From Disassembly it seems that the exception happens immediately after the assignment, but before the next line of code. I'm guessing this is where some debugger code gets executed:
Screenshot of disassembly
Maybe debugger did not expect for that line of code to be executed, because I altered the execution path with "Set Next Statement" command (moved from the "else" block into this one). Same thing happens if I alter the code (remove the "if") while the debug is running, but the problem does not repeat if I rerun the encompassing procedure after the edit.

How to detect a bad way of re-throwing a C# Exception using StyleCop or VS2010?

My colleagues are seasoned C++ hackers switching to .Net. One of the mistakes that they make unintentionally is writing code like this:
catch(ArgumentExcepttion ae)
{
// Code here logs the exception message
// And this is supposed to re-throw the exeception
throw ae; // as opposed to throw;
// But, as we all know, doing this creates a new exception with a shorter stack trace.
}
I have seen this done in many many places. I cannot really think of a situation where cutting off the stack trace would be useful. I think that should be exceptional situation that deserves a comment. Correct me if I am wrong. If the stack trace is to be cut, I think it is always better to do:
throw new ArgumentException("text", ae /* inner exc */);
Anyhow, what I want to do is detect all such cases and give a warning. A regular expression search is of no help, because of this:
catch(Exception e)
{
Exception newExc = new Exception("text", e);
Log(newExc);
throw newExc;
}
I would have to use a tool such as StyleCop (which I have, version 4.3.3.0 ). I am using VS2008 for now, but will be switching to VS2010 very soon.
Any thoughts on how to accomplish what I am looking for?
FxCop has a rule for this: RethrowToPreserveStackDetails
Once an exception is thrown, part of
the information it carries is the
stack trace. The stack trace is a list
of the method call hierarchy that
starts with the method that throws the
exception and ends with the method
that catches the exception. If an
exception is re-thrown by specifying
the exception in the throw statement,
the stack trace is restarted at the
current method and the list of method
calls between the original method that
threw the exception and the current
method is lost. To keep the original
stack trace information with the
exception, use the throw statement
without specifying the exception.
I believe FxCop Analysis is built in to VS2010 but I'm not 100% sure...
Here is the Microsoft download link for FxCop.
Is the code catching exceptions unnecessarily? If you are only interested in logging the exception, then you only need an catch at the top level of your code (at the last possible point where you can do the logging). This could seriously reduce the number of catches you have to worry about.
I would suggest to look for catch-blocks ending in a throw ...; instead of ending with throw;.
Although you get some false positive, you can filter them out by hand.

LINQ enumeration list doesn't show up the error when accessed it for second time while debugging

I'm making a database call with linq and it is returning some results to me. Following is the code for the same:
var resultSet = DataContext.GetList(id);
foreach(var result in resultSet)
{
// do something here with result
}
After this, I try to access again same resultSet as below:
foreach(var result in resultSet)
{
// do something here with result
}
When I'm in debug mode it doesn't throw any error, instead it simply exits debug mode and execution is completed and focus comes back to page.
I want to know why it is not throwing any error in debug mode that I'm using the enumeration for the second time? Am I missing anything? All other errors are throwing exceptions even in the debug mode.
Update: I intentionally didn't do that second calling. It was done by mistake, but it took sometime for me to find that error, if it would have thrown an error, then I would have easily fixed it. This is reason I posted this question here.
Note: I'm doing this throw a ajax call.
I think if you go to Debug (Menu)> Exceptions and check the checkbox under Thrown for Common Language Runtime Errors. Now Visual Studio debugger should break when the error occurs and you should be able to see what's happening.

Categories