CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo (.com)

Blog moved to www.jeffreypalermo.com

Hiding errors is evil - level 200

Hiding errors:
  • Swallowing informative excpetions
  • Returning a magic value instead of the error
  • Ignoring errors
I'm sure many can relate this this experience:  I'm using an application or a programming API.  The code runs and returns.  I move on.  I find out later that the code failed, and the work was never done.

This scenario can kill an application's reliability and reputation.  When this happens, you don't find out about errors until some time later.  Because of this, you really can't say that the application is working correctly at any point in time unless you explicitly investigate a log somewhere where errors are stored.

Hiding errors makes life harder.  Finding out about errors when they happen makes for more reliable systems.  I'll give one quick example from the .Net Framework v2.0.  This example uses C#.
            

string loweredUrl "/mypage.aspx";

string loweredApplicationPath = "/myApplication";

 

string appRelativeUrl = VirtualPathUtility.ToAppRelative(loweredUrl, loweredApplicationPath);

Console.WriteLine(appRelativeUrl.Length);


This seems simple enough.  We're using the VirtualPathUtility class to convert a url to it's application-relative form.  In this case, I'm passing an invalid argument in.  The rule this method uses is that if the url is not a part of the given application path, it's invalid.  What does VirtualPathUtility do in this case?  It returns NULL!  I passed in an invalid argument, and it returns null.  The more appropriate response would be throwing an ArgumentException.  Because of this error hiding, I have to know the internal rules of this method and code around them.  I can't afford for this code to continue while appRelativeUrl is null.  The next line would throw a NullReferenceException.

Because of the error hiding, my code ends up like this:

string loweredUrl "/mypage.aspx";

string loweredApplicationPath = "/myApplication";

 

if (!loweredUrl.Contains(loweredApplicationPath))

{

    throw new ApplicationException(string.Format("url {0} is not in application path {1}", loweredUrl, loweredApplicationPath));

}

 

string appRelativeUrl = VirtualPathUtility.ToAppRelative(loweredUrl, loweredApplicationPath);

Console.WriteLine(appRelativeUrl.Length);


I have to do an explicit check and compensate for the undesirable behavior of the API.

If an error condition happens, I want to know about it.  The term "fail fast" is very popular.  It means that if the application encounters a condition where it can't continue, stop now and output the exception information.  Don't have the application limp along until it crashes in flames.  If you break your arm, you stop what you are doing and get a cast put on.  Yes, you _could_ go to work if it's not your mousing arm, but you cause less damage if you stop right away and address the problem.


Comments

Jeremy D. Miller said:

A-freaking-men. James Shore wrote a great article on this --> http://www.martinfowler.com/ieeeSoftware/failFast.pdf
# March 9, 2006 10:10 AM

johnwood said:

According to the docs, ToAppRelative should return the path unchanged if it's not part of the application path. So I guess that's a bug. I'm not sure it should raise an exception unless there is another method that will tell you whether the path is relative. Hate functions that validate data by throwing an exception, it's a misuse of exceptions.
# March 9, 2006 10:56 AM

Jeffrey Palermo said:

John,
Thanks for lookup up the documentation. I don't normally make that a habit since I can look at the actual code with Reflector.

I don't think it's a misuse of exceptions. How else can a method communicate that it can't continue if an argument isn't valid. If it didn't validate with an exception, then another exception would happen naturally: NullReferenceException. An exception will happen somewhere if input is invalid. I'd rather it happen as close to where the actual error is.

In my code sample, if I had an exception, I'd know that I can't use the method in that fashin. I would _not_ try/catch the method as a means of code flow. I would take steps to validate my own argument before calling the method. Even if the class had a "IsPathValid" method, all programmers aren't going to call that method.

I like the concept of pushing complexity outward. Code that I write will only work if my assumptions are met. I assert my assumptions by throwing exceptions.
# March 9, 2006 11:45 AM

johnwood said:

Jeffrey,
It's a tricky one. So long as there *is* a way to validate input independently of the function then I would tend to agree with you that throwing an exception is acceptable. I just wouldn't want to rely on that function not throwing an exception as a means of validating the input. I think we're on the same page though. Either way the function isn't working the way it should :)

John
# March 9, 2006 11:59 AM

Eber Irigoyen said:

while I agree on everything you said at the beginning, that specific example can be debatable (is that a word?), basically it all comes down to error codes (of some fashion) or exceptions, and you have to remember the rules for exception, use exceptions only in exceptional cases, I can see your point of view, and it is very convincing, but still this can be one of those religios debates
# March 9, 2006 12:05 PM

Jeffrey Palermo said:

Debate is good. I don't think I'm religious about coding because I find myself being convince of different things when confronted with a good argument. I like code to be "correct", but I'm also party a pragmatist, though not completey.

In a language that supports structured exceptions, I prefer to use them. It's so easy (but not for program flow).
# March 9, 2006 12:15 PM

About Jeffrey Palermo

Jeffrey Palermo is a software management consultant and the CTO of Headspring Systems in Austin, TX. Jeffrey specializes in Agile coaching and helps companies double the productivity of software teams. Jeffrey is an MCSD.Net , Microsoft MVP, Certified Scrummaster, Austin .Net User Group leader, AgileAustin board member, INETA speaker, INETA Membership Mentor, Christian, husband, father, motorcyclist, Eagle Scout, U.S. Army Veteran, and Texas A&M University graduate. Check out Devlicio.us!

This Blog

Syndication

News

Headspring Systems

View Jeffrey Palermo's profile on LinkedIn

See my new blog at .jeffreypalermo.com