Wednesday, September 5, 2007

Exception Handling

When I first made the transition from Java to C# one of the differences I quickly ran into was exception handling. Java takes a very strict approach where methods must declare every type of exception that it could potentially throw. If you don't declare it, then you don't throw it. That means that when you call a method that declares to throw one of seven exceptions, you need to either catch or yourself throw all of them. Of course, in practice there were actually two different options that I saw people using. The first, and preferred method, was to wrap calls with try/catch blocks and then wrap the caught exceptions with your own custom type. This lead to the types of exception traces you might see with JBoss, where one little FileNotFoundException could lead to litterally hundreds of lines of stack trace with 5+ nesting exceptions... each one providing less and less useful information. The second method was to simply declare that your calling method threw java.lang.Exception and call it good. The biggest motivator was that it allowed the programmer to provide additional context as to the state of the application when the exception occurred. If an exception was thrown while saving an object to the database, we would wrap the SQLException with our own custom exception and provide the ID and type of the object being saved. This greatly helped in debugging.

In fact, I remember spending a significant amount of time thinking about and even more debating various methods for exception handling. At one point I was working on an a bit of logic that was (at compile time) inserted into all of our throw statements to create an 'exception session' to tie together a chain of logically disparate exceptions. Looking back, this was a complete waste of time.

When I first started looking at C# code I noticed that none of our methods declared the exceptions they could throw. To my horror, I found that we pretty much were only catching exceptions at the top level of the application (ie: just before you see the 'Error, had to crash' dialog). That's not to say that there wasn't some sparse exception handling thrown in the mix, but by and large we let problems propagate out. The first bit of code that I contributed to the project handled exceptions just like a good Java programmer should. I caught all over the place and threw out custom exceptions, wrapping the original problem with some additional context information. This worked fine, but also resulted in the same kind of JBoss-esq monster exceptions. When the database was missing a column the developer saw a XamlParseException... pretty much exactly what you want!

try
{
...
}
catch (SomeException se)
{
if (!se.Data.Contains("My.Context"))
{
se.Data.Add("My.Context", myContextObject);
}
throw se;
}


Yesterday I was going back through and cleaning up exception handling when I discovered the Data property of System.Exception. Data is a Dictionary that takes string keys and object values. I can't remember the last time I was more excited at finding an API gem. It's pretty sweet when a tiny difference can make such a huge impact on ease of use. Now, when I want to provide some additional context during an exception event I just add some data values. At the top level we have a single method to build a nice looking report from an exception. The developer gets to see the actual problem right off, but can also find out what was happening deep down in the core.

Monday, August 6, 2007

Awesome tool for sharing keyboard+mouse

Erik told me about an open source project called Synergy that allows you to share a keyboard and mouse over any network connection. I originally tried it out at home, where I have a Mac G5 and a Windows XP machine. Both machines have their own monitor, keyboard, and mouse. Synergy ended up working awesome for this setup because I

  1. got to clear off some desk space now that I only needed one keyboard/mouse setup and

  2. allow me to be way more efficient when working because I started using them almost as one machine.

In addition to sharing a keyboard and mouse Synergy also lets you share a clipboard! This makes coding on one machine while doing searches/research on the other super-efficient. Overall it's a super useful tool... for free!

Friday, June 15, 2007

Merge and Goto Sadness

Almost two months ago I went off on my own branch of the source tree to make some restructuring and refactorings. Wednesday I finally finished my changes (or, got them close enough to begin bringing them back into the trunk) and am now in the process of merging. I found a pretty sweet tool for performing individual file merges named Guiffy. It's a $75 tool, but is free for 21 days (which should be more than enough time for my process). The critical feature it provides is character-by-character diffs. Given some of the changes I've made, this is huge. It also seems to be pretty good about correlating changes that effect line numbers. It's not perfect, but certainly good enough.

While merging, I came upon a statement that made me really, really sad. C# supports goto statements?!?!? I thought that goto had been recognized long ago as a bad idea. What gives?

Tuesday, April 10, 2007

Working with XBAP

When running an XBAP from within Visual Studio 2005, there are some caveats. If you want to be able to debug the XBAP you need to run VS NOT as an administrator. In addition, you cannot be running any other IE processes.

If you do run as an Administrator, the XBAP will not automatically reload between runs. To get it to reload you need to clear out the application cache. Run the 'CMD Shell' application (part of the Windows SDK) and enter:

mage -cc

This should cause your cache to be cleared, and the XBAP should reload with any changes the next time you run.

Monday, March 19, 2007

First Week

My first week here at Agile I've been working on a few different things. First, I've been digging into the Huddle code base. I brushed up on the basics of WPF and even wrote a simple application in XAML before starting last Monday. Now I get to dive in head first to, basically, every feature WPF offers. Along with that I will need to learn WCF. C# is close enough to Java that the transition is looking to be straight-forward. Separately from getting to know the Huddle system, I have been investigating issue tracking systems.

TRAC looks to be a decent system for tracking issues, but I know there are better systems out there. At UNL I used a system named Jira, by Atlassian. Compared to TRAC or Bugzilla, it is a joy to use. Managing issues, tracking change history, and generating reports is super-easy. Jira also has a nice dashboard portal value-add that is useful for viewing the overall progress of a project. It gives a nice '50,000 ft' view from above look at a project (or projects). One thing that we never got into a UNL is workflows.

Pretty much every issue tracking system has some notion of a workflow. This allows the development group to lay out, in the system, their process for doing work. In practice, a workflow may look like the following:

  1. A tester discovers a bug, and creates an issue. The tester isn't sure exactly who the issue should be assigned to, but the workflow would auto-assign it based on the component. In addition to auto-assigning the task, the workflow auto-assigns a tester who is in charge of that component.
  2. The issue is automatically assigned, and the assignee developer receives an e-mail notification.
  3. The developer finishes his other tasks, and is finally ready to begin work. He marks the issue as 'in progress' and begins work.
  4. When the developer feels the issue is completely resolved, he marks the issue as 'resolved,' which then sends an e-mail notification to the tester and assigns the tester as the new 'owner' of the task.
  5. The tester runs through and discovers that the bug isn't totally finished, so she marks the issue as 'reopened'. Again, the developer gets an e-mail and is auto-assigned.
  6. Steps 3-4 are repeated, and this time the tester feels that the issue has been completed. She marks the issue 'closed' and the process is complete.

That is a pretty average case scenario for how work might be done, but the workflow automation allows each person to focus on his/her work without having to coordinate with the component developers to know who is best able to resolve the issue. This also prevents an overall manager from having to intervene and delegate issue assignments. As teams grow, minimizing the need for constant communication is going to become more and more important.

I've been evaluating several different systems for managing issues. The most important attributes I have been looking for include:

  • Web Access - a lot of the systems have a Windows client, but web access is convenient
  • Requirements Tracking
  • Test Plan Management
  • Customer Access features - this comes in a wide variety of flavors
  • SVN integration - I think this is pretty important
  • ActiveDirectory Authentication - most of them support LDAP authentication, so we should be good there
  • VisualStudio .NET integration - this would add a lot of convenience
  • Ability to import existing TRAC tickets - I think some level of import would really ease a transition from TRAC to the new system

I have been spending more time on this investigation than I originally intended. I think that, if we are going to move to a new system, we should do it while the team is still very small. The need for a more formal process is going to grow with each new hire.