Why can't I write better exceptions for myself?
Intro
After spending some time debugging an exception thrown by a code written by myself (I know, duh!), I was wondering why the hell can't I write better exception messages. I mean, just the exception type is clearly not enough. I'll demonstrate:
Scenario
I have a class that uses a configuration from AppSettings called "MyConfig". If I can't find the Configuration (if it's null or empty in the app.config or web.config) I throw an exception like this:
throw new InvalidOperationException("MyConfig cannot be null or empty");
Problem
I know that I could expand on that message and improve it so that it would be actually helpful. But as I always do, I started wondering why is that. Why I don't write the correct way the first time around? I know for sure that it would save me countless hours wasted on debugging. Or get a custom exception type for each scenario, but I'm lazy (more on that in the conclusion).
Solution
So the best solution I found was to design a fluent interface to wrap what I think a good exception message should be. The result is explained below.
Fluent Interface for Exception Throwing in Stormwind.Common
Right now this is what an exception throwing looks like, in its most comprehensive form:
1: Throw.WithMessage("Something happened") 2: .WithWhy("Why did this happen") 3: .WithWorkaround("What can I do about it") 4: .WithInnerException(new InvalidOperationException("some inner exception message")) 5: .Exception<InvalidOperationException>();
Now, using positioned arguments for exception constructors:
1: Throw.WithMessage("Something happened") 2: .WithArgument(0, "Parameter Name")
3: .WithWhy("Why did this happen") 4: .WithWorkaround("What can I do about it") 5: .Exception<ArgumentNullException>();
At this point you would ask me:
Hmmm...Don't know... Too much code, dude... I don't want to write all that just to throw an exception... I get paid by the hour you know?
Yes, I do know that. And that's why you can use just as much information as you want to:
Throw.WithMessage("Something happened").Exception<InvalidOperationException>();
I don't think I will, though. I really like being able to specify why and what to do in case an expected exception is thrown. This way I don't shoot myself (and specially anyone that's using my code) in the foot again.
Conclusion
I'm a lazy programmer and I need my tools to push me in the right direction. That's just how I am... Nothing I can do about it, now is there?
If you want to try that code by yourself just do "svn co http://svn.stormwindproject.org/svn/Stormwind.Common/" and open the solution file in \Trunk\Baseline. The Throw class is in the Stormwind.Common.Core assembly.
Opinions?
#141