Unless you have a VERY good reason, rethrow your exception.

I see it a lot, people write a function, they catch a possible exception and throw one of their own OmgSomethingHorribleHappenedException();

Check this simplefied example:

private static void Main()
{
	try
	{
		var result = (new Api()).Find("foo");
 
		Process(result);
	}
	catch (Exception e)
	{
		Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
		Console.Read();
	}
}

And the Api.Find(string toFind) method:

namespace ExceptionRethrow
{
	using System;
	using System.Linq;
 
	public class Api
	{
		public string Find(string toFind)
		{
			try
			{
				// force a InvalidOperationException
				return (new string[] { }).Single(e => e == toFind);
			}
			catch (InvalidOperationException e)
			{
				Logger.Log(string.Format("Tried to look for element {0}, not found", toFind));
 
				throw e;
			}
		}
	}
 
	public class Logger
	{
		public static void Log(string message)
		{
			Console.WriteLine(message);
		}
	}
}

As you can see in the Api.Find method we catch the exception from the Single call, log the error (to notify the developers or something, …) and throw the exception again.

However when we look at the call stack in the Main method we see this:

e.StackTrace

Odd, what’s line 19 in Api.cs? Right, throw e. Useful! NOT!

So you need to replace the throw e by throw.

//...
catch (InvalidOperationException e)
{
	Logger.Log(string.Format("Tried to look for element {0}, not found", toFind));
 
	throw; // removed the 'e'
}
//...

Then the result will look like this:

e.StackTrace

Now we already know little more about the cause. However to improve we need to catch the error, and throw it again by passing in the current exception as inner exception:

//...
catch (InvalidOperationException e)
{
	Logger.Log(string.Format("Tried to look for element {0}, not found", toFind));
 
	throw new InvalidOperationException(e.Message, e);
}
//...

So let’s debug again:

e.StackTrace

Again we only see the lines where the exception was thrown last, however when we investigate the InnerException’s stacktrace we get way more info:

e.InnerException.StackTrace

Now that’s an exception that’s useful to debug Smile

We can leverage this knowledge in multiple ways, one of which is shielding exceptions, making sure none go through to the client. For example when your service broker detects an error, it clears the InnerException field, thus removing any business knowledge from the exception.

When in debug mode you can want to send over those exceptions to improve the finding of bugs Smile

You can find the complete example on GitHub.

Have a good one,

-Kristof