Throw InnerException without loosing the stack trace

February 5th, 2010

How to throw the InnerException of a TargetInvocationException without loosing stack details?

I’ve been plagued by this problem for some time. There are a few common solutions to this:

  1. Option #1 - just leave it alone. The downfall here is that specific types of exceptions cannot be caught easily in calling code. In some instances this can be a very big problem.
  2. Option #2 - re-throwing the InnerExcpetion property. This at least preserves the type of the exception and thus code above you in the call stack will correctly catch and handle exceptions. The problem here is that the stack information previously held in that exception is lost.
  3. Option #3 - Avoiding the problem. If you know the types of the calling parameters you can construct a delegate from the MethodInfo. By calling the delegate (not using DynamicInvoke) the issue is avoided. Again this only works if you have compile-time knowledge of the parameters.

 
Most of the time one of the above has been an acceptable solution; However, recently I ran into the case where none of the above would work. The code has been around a while using option #2 above since the arguments are unknown. Changing the behavior to not throw the original exception type was out since it could break existing client code. The problem that was killing me was the loss of the stack when debugging and monitoring log information. The loss of this information was making spend hours trying to figure out where the thing failed.

So I needed to use MethodInfo.Invoke(), needed the stack and the original excpetion type to be persevered… but how?

Well the first thing I came up with is the following routine which gets down-and-ugly with the Exception class. The catch-block finds the inner-most TargetInvocationException and extracts the InnerException. Then using the Serialization helpers it basically copies the fields of the object to an array. Now we re-throw the exception to set it as the ‘current’ exception when we next call throw without an argument. And finally after we’ve lost our stack we stuff it back in by calling the Serialization helper again to push all the fields back into the exception before calling throw one last time.

Bad Code, do not use

[System.Diagnostics.DebuggerNonUserCode]
[System.Diagnostics.DebuggerStepThrough]
private static void Invoke(MethodInfo method, Object target, params Object[] invokeArgs)
{
	try
	{
		method.Invoke(target, invokeArgs);
	}
	catch (TargetInvocationException te)
	{
		if (te.InnerException == null)
			throw;
		Exception innerException = te.InnerException;

		MemberInfo[] fields = FormatterServices.GetSerializableMembers(innerException.GetType());
		object[] values = FormatterServices.GetObjectData(innerException, fields);

		try { throw innerException; }
		catch(Exception exception)
		{
			FormatterServices.PopulateObjectMembers(exception, fields, values);
			throw;
		}
	}
}

This all worked well… However, I started to wonder about how this might effect some types of exceptions. I started thinking maybe I should serialize & deserialize the object first. I started thinking I was making this too complicated just to preserve a stack trace.

I finally just started reading the exception code and found they have exactly what I want already baked in… just not exposed. The method only preserves the stack, nothing else… perfect. So why not solve a reflection problem with reflection:

[System.Diagnostics.DebuggerNonUserCode]
[System.Diagnostics.DebuggerStepThrough]
private static void Invoke(MethodInfo method, Object target, params Object[] invokeArgs)
{
	try
	{
		method.Invoke(target, invokeArgs);
	}
	catch (TargetInvocationException te)
	{
		if (te.InnerException == null)
			throw;
		Exception innerException = te.InnerException;

		ThreadStart savestack = Delegate.CreateDelegate(typeof(ThreadStart), innerException, "InternalPreserveStackTrace", false, false) as ThreadStart;
		if(savestack != null) savestack();
		throw innerException;// -- now we can re-throw without trashing the stack
	}
}

The person that made this ‘internal’ should be flogged. How very easy of a solution that is and perfectly safe for all types of exceptions. It appears it will even work with remoting, serialization, cross app domains, etc.

My first request for .Net 5.0:

partial class Exception {
	public void PreserveStackTrace();
}

Updated: Apparently this isn’t a new hack, I should have done some google’ing ;)

Another quick word on TDD vs Integration testing

October 6th, 2009

After writing my last article I began to wonder what people ‘in-the-know’ thought the advantages of TDD vs integration testing were. So I quickly turned to my new favorite site stackoverflow. After reviewing several questions I came across this one entitled “Is Unit Testing worth the effort?“, and the accepted answer had 113 votes. So if you haven’t already, click the article title and read the arguments for using TDD, then read on for my responses.

Most of these apply to Integration Testing as well as TDD testing with a few that might be questionable. Let’s discuss those:

2. TDD helps you to realise when to stop coding. Your tests give you confidence that you’ve done enough for now and can stop tweaking and move on to the next thing.

Assuming your not ‘master-planning’ this should not be a problem. Write your code as-needed (YAGNI) is a principal that stands apart from TDD. This developer ‘tendency’ is also easily mitigated with requirements on test coverage %, the ‘over-engineered’ solution is less likely to be introduced if the developer is required to hit 100% functional coverage in integration testing.

4. TDD helps with coding constipation. When faced with a large and daunting piece of work ahead writing the tests will get you moving quickly.

I haven’t heard this argument before. *shrug* +1 for TDD, but I really don’t have this problem. I (and I’m most Sr Dev/Architects would agree) continually break down large tasks into small achievable goals every time I write a piece of functionality. Perhaps there is merit here for newbies, but I would guess that TDD as a whole is very beneficial for controlling the damage a newbie can cause. For the rest of us, simply writing TDD tests doesn’t mean you’ve adequately broken down the conceptual model of the coding problem.

5. Unit Tests help you really understand the design of the code you are working on. Instead of writing code to do something, you are starting by outlining all the conditions you are subjecting the code to and what outputs you’d expect from that.

I’m not sure how this applies to ‘design of the code’; however, the later part of the statement is valid. Capturing with tests the ‘behavioral contract’ of an object’s interface(s) is essential. This is and should be done by writing the client code first, even if it is just pseudo code. You should not be ‘throwing together’ interfaces without having reviewed it’s intended use. If TDD does this for you, great, I myself believe that the typical TDD (single AAA pattern) does not allow me to truly ‘feel out’ the client code. You can’t get a sense of the difficulty of using an interface is when only accessing a single method/member at a time. It breaks the flow of the intended client usage pattern into small granular chucks and that changes the things that you find cumbersome or difficult. TDD (IMO) is not a valid experience of writing the client code.

6. Unit Tests give you instant visual feedback, we all like the feeling of all those green lights when we’ve done. It’s very satisfying. It’s also much easier to pick up where you left off after an interruption because you can see where you got to - that next red light that needs fixing.

This I can totally see and agree with. Almost all developers enjoy a feeling of accomplishment from their work. Often while working on large projects it can be difficult to obtain. I think everyone needs small milestone gratification from the efforts, I enjoy the check-in to integration. As my build tells me I’m tested, working, and ready to be used, this is my moment of joy. I may not achieve this 20-30 times a day, but the two or three are very gratifying.

So in summary I again attest that TDD is cool and all, but it is not essential to a good piece of software. Testing; however, is required and the biggest thing I like about TDD is that finally got the rest of you writing unit tests :) I’ve been doing integration testing since 2000 and using NUnit+coverage since 2002 and I must say hardly anyone seemed to care about testing their own code back then.

Here is a good story from Mars on testing code

October 6th, 2009

I was viewing the comments on a recent post entitled Integration Tests Are a Scam when I ran across this:

Integration tests are needed
A Mars rover mission failed because of a lack of integration tests. The parachute subsystem was successfully tested. The subsystem that detaches the parachute after the landing was also successfully (but independently) tested.

On Mars when the actual parachute successfully opened the deceleration “jerked” the lander, then the detachment subsystem interpreted the jerking as a landing and successfully (but prematurely) detached the parachute. Oops.

&nbps;
What a great story. I concur with the author that “Integration tests are needed”, moreover, IMHO if your going to have only one or the other integration tests are far more important than TDD/isolation tests.

I have not yet delved into Mock frameworks or the like. I just don’t think they are necessary to perform a good job testing. My own library on code.google.com (IMO) speaks volumes about testing code without anything fancy. Ok, my tests are ugly I agree; however, they do catch most of the behavior of the public interfaces. I don’t use reflection to test code, I don’t expose members solely for the purpose of testing, and yet I continually average 95% statement-level coverage. My build asserts that 100% functional coverage was obtained and this helps keep dead code or useless code out of the source tree.

I’m not much on the whole TDD thing as anyone can tell by reading my tests. I do strive to design client-code first which I believe is very important. I also endeavor to not over-engineer things, adding what I need, as I need it, rather than building it all up front. I test everything I write. Why do I need TDD to do what is obvious and should be done as a natural part of development? Maybe I’m just too old to get it.

Ahhh, alas I’m not the only one who hates the ‘if’ keyword

August 27th, 2009

Ok, I just found the best site I’ve stumbled across in a long time.

http://www.antiifcampaign.com/

Excellent job guys and mad respect for giving this issue it’s very own online site/campaign. Join me and the many others to move the community in a positive direction. BTW, I found this indirectly on a great post about the subject by elegantcode.com.

If you don’t remember, I disscussed this a while ago with What-if if is evil? But I would be remiss to avoid mentioning that the if keyword is not the only way to write branches in your code. There are plenty of other keywords (switch, while, try/catch) that can produce the same issues. The idea should be to create functions/methods with the fewest code-paths as possible. This creates code that behaves more consistently, predictably, and is easier to read and test. This is especially important when writing code in a Form or ASP code-behind.

TDD Tests are not Unit Tests - Stephen Walther

April 13th, 2009

For those of you struggling to understand the different approaches to testing being heralded in by the TDD community I strongly encourage you read the following article:

TDD Tests are not Unit Tests

Stephen does an excellent job of detailing the general purpose behind the testing styles and really clarifies for my why I tend to disagree with many of the assertions about unit testing from the TDD community. First let me say I don’t do TDD, and generally I fundamentally disagree that it produces better software.

What I do believe in is testing your code via unit tests (call it integration testing, acceptance testing, whatever). I have been testing code via NUnit since 2002. Perhaps I may be set in my ways, I just can’t seem to join the TDD ‘gold rush’. There might be a reason for TDD (test before code) if you are doing one of the following:

  1. Giving one or more interfaces to a Jr team member for implementation
  2. Working tightly with a remote team member
  3. ??? Ok, short list because I can’t find any other reason ???

Maybe I’m crazy, but ensuring product/component stability and a general confidence in changes are the only goals for me. With one side benefit of either learning an API or providing a sample usage of one.

Multiple asserts in a test?

March 24th, 2009

Recently I’ve been following Roy’s ISerializable blog’s series on test-case reviews:
Test Review #1 – NerdDinner
Test Review #2 – ASP.NET MVC
Test Review #3 – Unity

They have been fairly informative and full of insight into Roy’s view of proper testing. One thing he keeps commenting on continues to strike a nerve of mine. Roy clearly believes that a single assert per test is THE way to go. My problem is I still fail to see his reasoning here. He has stated in all three videos that this is a bad idea since all the asserts after the first failure will not execute. OK, this is true; however, isn’t the goal to make it all pass and if so why does it matter? Even if the arrange/act of the test is only 1 or 2 lines, I would be livid with a developer that copy/pasted those lines into 20+ functions just so he could have a single assert per test. Doesn’t that make it unmaintainable? Doesn’t spreading this across 20+ methods make it hard to read?

What are your thoughts? Do you write a single assert per test? How much duplication of code do you then suffer?

(adj) agile: aka adaptive; see also plan for change

March 23rd, 2009

I seem to find myself talking with developers that seem to have some fixed notion of agile development. They speak like it’s an implementation of XP (eXtreme Programming), or TDD (Test Driven Development), or some other fairly concrete methodology. Maybe it’s just me, but I really think this misses the whole point?

In my world, agile development is simply the practice of being prepared to change. When you apply this generic statement across the entire development process you start getting a picture of what I’m talking about. It’s not just about test cases, refactoring code, or any other concrete thing. It’s a mindset that adapts across everything you do.

Why do we write unit tests for our code? So we can change it.
Why do we use interfaces instead of class names? So we can change it.
Why do we use DI (Dependency Injection) or IoC (Inversion of Control) to some? So we can change it.
Why do we design as needed only what is needed? So we can change it.
Why does a release not have a fixed set of features? So we can change it.

Being an agile developer is about recognizing one of life’s truths: “Things change”. We expect it, plan for it, adapt to it, and ultimately embrace it in everything we do.

PS: Have you noticed being adaptive to change is also a great skill outside of work ;)

Simple is always better

March 18th, 2009

This is the one, the only, the quintessential rule to programming.  AKA, the KISS method (Keep It Simple Stupid) is, to me, words to live by.  From the implementation of a simple class to the design of a complex application you constantly have to keep this in the forefront of your mind.

Far too often I see the most talented of developers letting themselves get carried away with something they are working on. This inevitably results in the worst kind of code, over-engineered, over-complicated, and under-tested. I presume this is caused by their own miss-guided love of a project or component they are working on. Open source software often exhibits this, I would guess this is due in part by these projects being developed by those who love the project.

I have often been guilty of this pleasurable curse myself. The only effective way of curtailing this innate behavior has been two things. First, constant reminder of KISS, and second, self discipline in extensive unit testing. Honestly, the later serves better than the former… having to test everything you write often kills unnecessary and frivolous features. I would guess the best example I have of KISS is the silly little ‘Check.cs‘ file I created. Since I have not needed more than it’s 3 or 4 methods I have not written more. I have not added to this class not because I can’t imagine a whole host of other routines than could be added and perhaps useful *someday*. Rather I have not added anything I did not have an immediate need for very intentionally.
 
For those of you still confused: Simple Code == Less Code == Less Bugs