10 August, 2011

It seems that I always have the following conversation with different developers.

Them: This method shouldn't throw an exception, it should return an error code.
Me: OK. Why?
Them: Because... umm... exceptions are a terrible means to communicate errors. I want to see a status flag and an error message.

I kinda get the point, but in frameworks such as .NET and Java, it really doesn't make sense to use anything but exceptions.

First, if you use error codes or anything of the sort, you now have the worst of both worlds: the runtime and class library code will throw exceptions and your code will return error codes. Now you have to deal with both.

Second, when returning error codes and messages you have to make assumptions about how application developers will use your code. It's impossible for you to determine under what conditions your code will be used and what assumption the application developer will make about it. It's best to just be consistent and throw an exception when you're not able to complete the work you "contracted" to do through your method signature.

In the interest of completeness: there's perhaps one case in which you should return a flag instead of throwing an exception. When you have a method that gets called frequently and it also has a high failure rate, you'll likely experience a performance hit (from throwing/handling so many exceptions) that won't be tolerable.

Microsoft, for example, had the above problem with the Int32.Parse method. To address the issue MS introduced TryParse. This new method returns a flag telling you whether worked and returns the value of the parse in and output parameter called result.

It's important to note, however, that the boolean flag returned only indicates one type of failure: the method's inability to parse the string into an integer. The method still throws an ArgumentException if the argument is not valid.

So there you have it: always use exceptions. And if you're not going to listen to me, use error flags to indicate just one type of error.

03 May, 2011

For the past few months we've had this bug (PROD only, and unreproducible in any of our other environments) where every now and then we could not get data from our DB. The DB was up and running just fine, but the SqlClient on the web server just could not read the data (we'd get 2 errors: one about trying to read data where a reader was already open, and another about not being able to cast the data from the reader to a certain type). In case you're interested, the exact errors were:

System.InvalidCasException: Specified cast is no valid. At System.Data.SqlClient.SqlBuffer.get_Int32()

Invalid attempt to call Read when reader is closed. Somewhere in System.Data.SqlClient as well.

For a while we just lived with the error; it didn't happen very often and it only affected a few customers. Then the problem got worse and so we immediately blamed it on some environment change... we recycled the app pool on a consistent basis while trying to figure out what the problem was.

Finally, when the problem got bad enough, I did a little bit of research and concluded that we were seeing the problem because we were not disposing our LINQ contexts correctly. After trying to prove that the problem was in someone else's code (and failing), I quickly concluded that it must be Unity that was not disposing the contexts.

You see, I had assumed that Unity would new up an instance of our db context on every call to resolve, but it turns out that by default the lifetime of the dependencies Unity resolves is the same as the lifetime of the IoC container. In our case, the IoC container stayed alive throughout the entire app (because we needed to resolve stuff in our MVC controllers) and so the longer the app went without a restart, and the more requests it handled, the more we saw the error.

Fortunately, because we were using Unity to resolve all of our dependencies, and because the Unity code was all in one place and well isolated from the rest of the app, it was really easy to fix. All I had to do was write a per HTTP request lifetime manager and plug it into our container. I'll be posting the code for that container soon... but now I gotta go to bed. Looks like we'll have quite a few bugs to fight tomorrow. :)

20 January, 2011

honoring the title and idea of this post i'll just say this to get the point across:

the quality of your solution is inversely proportional to the amount of code you write to solve the problem.

unfortunately, i have to say a bit more to justify my thoughts.

i've always wondered about how to write good code; and i'm not the only one apparently:

well, i've finally figured it out: good code is written by writing as little code as possible. this is true because the when you write the bare minimum you will almost naturally end up with code that is easy to read, easy to test, easy to extend, and therefore, easy to maintain (to see more about the attributes of good code, take a look at the pyramid of code quality).

i understand that there are guidelines and principles that you must still follow when writing "just enough" code, but things really deteriorate fast when you don't KISS.

so next time you're inclined to do solve a problem with code, first think about if there's a way to solve it without any code. then, and only if you absolutely must, write as little code as possible.