Tag Archives: software development

How to Not Suck at Exception Handling

Yesterday a co-worker sent me an email about an error that was reported to them. “Have you seen this error before? If you have, can you tell me what it means?” This is a huge pet peeve of mine. Too many developers view exception handling as nothing more than an anti-crash mechanism. When an exception occurs, it gets logged and ignored. If the application’s not working, somebody might look at the log and see a repeated error message in the form of an exception.ToString(). That exception gets reported and travels electronically through the ranks until it makes its way back to the developer: “Oh, that exception?” the developer replies, “That just means the certificate is missing.”

Oh, that’s it? Thanks for the info, but I’ve got news for you: you failed. If you can say “That exception means…” then that’s what the application should’ve reported to begin with. Further, an explanation like this should only be forgivable if it’s followed by “I’ll update the application to say that.” Accepting “<insert exception here> means <actual problem>” as a solution should be unacceptable to all parties involved.

The good news for developers is that this isn’t a hard problem to solve: you just have to not suck at exception handling. The even-better news is that it’s not hard to be a good exception handler, you just have to think about what you’re doing and follow a few easy steps.

Reduce exception handling

My smelly-sense definitely goes off when I see code that has exception handling in every single function. This obviously depends on the code–maybe it’s necessary–but you should try to only include exception handling where it’s needed. If you can’t think of anything that can go wrong, don’t cover it up when the unthinkable occurs.

Of course, if you can think of things that might cause exceptions…

Catch specific exception types

This is where you look at your code and think of everything that might go wrong. If you’re writing a file, what happens if you don’t have permissions or the directory is missing? If you’re calling a web service, what happens if the service isn’t available? What happens if you access that database with invalid credentials? Each of these problems produces a specific exception type that can be caught and handled in its own special way. If you know where an exception could occur but don’t know the specific exception type, test to find out.

It would be rude in all of these scenarios to simply pretend that everything is okay and move on. Instead, do the courteous thing…

Provide meaningful messages

Don’t just tell people what happened, tell them what it means or what they can do about it! Should they restart the application? Do they need to contact an administrator? Is it connection problem? Is this going to resolve itself?

I mean, don’t get me wrong: System.ServiceModel.Security.SecurityNegotiationException “SOAP security negotiation with http://localhost/someservice.svc for target http://localhost/someservice.svc failed. See inner exception for more details” is a terrific error, but you’re not doing anybody any favors by showing it in a message box or writing it to a log. Doing something like that is just begging to be bothered for interpretation later. Instead, provide a meaningful message: “A security negotiation exception occurred. Verify that the certificate exists and has appropriate permissions.”

Remember that updating these messages is an important maintenance step. If a new cause for an exception is identified, be sure to add relevant information to your messages to make them as helpful as possible!

Don’t eat exceptions

One of the worst things you can do is to “eat” exceptions. I’m talking about adding try { … } catch (Exception) { } around all your code where the catch logic does nothing or quietly logs some details without indicating any problems to the rest of the application. I’m not suggesting that you let any and all unaccounted for errors crash your application, but allowing exceptions to fail as loudly as possible will lead to a more robust end product. The squeaky wheel gets the oil, you know? If you follow the guidance above, a new exception that was previously unaccounted for will result in code that specifically handles the newly identified scenario and provide meaningful information. The next time the exception occurs, there should be no mystery around what caused it or what should be done as a result.

Test everything*

*Everything that you can think of. The end goal of most applications is (or should be) to create a positive user experience. To that end, when you’re adding exception handling for specific scenarios and providing meaningful messages, you should verify how it will present to the user. If it’s something the user needs to address, make sure they receive clear information about what they should do. If the user needs to contact somebody, such as an administrator, make sure they know what to tell them. If something happened that the user doesn’t need to worry about, maybe you want to make sure that they can’t tell it even happened. Whatever it is that you’re trying to do, test it and make sure it works how a user should expect it to.

Advertisements

Writing software involves…

Writing software involves figuring out something in such incredibly precise detail that you can tell a computer how to do it.

Taken from a blog post by Dan Milstein: Coding, Fast and Slow: Developers and the Psychology of Overconfidence

Extra McNugget Sauce, Scope Control, and Expectations Management

One of the biggest challenges that my team faces when working with customers on a software development project is controlling scope. These projects begin with a contract followed by a formal requirements document that must be signed by the customer prior to beginning development work. We’re realistic about this process; we don’t expect that every requirement will be correctly identified upfront, and we’re willing to work with the customer throughout the development process to ensure that their needs are met.

Occasionally, we’ll find ourselves working with customers that keep pushing scope, little by little, until the project has been stretched so far beyond the original requirements that we’re not sure how we got there. Kudos to that customer for getting some serious bang for their buck, but at some point we, the development team, need to draw the line. The problem in a lot of these scenarios is that we’ve given and given and given with little or no resistance. We’ve set the expectation that if they ask for something, we’ll give it to them. We can find ourselves with a customer that’s unhappy about being cut off despite delivering a lot more than was originally bargained for.

This scenario has two major flaws. There’s obviously the issue of scope control, but expectations management for the customer is equally problematic.

I like to use a McNugget sauce analogy here. If you go to McDonald’s five times and get an extra sauce with your McNuggets for free, you’re happy. But then, on the sixth visit, maybe you get charged for the extra sauce because it’s the restaurant’s policy. This would upset a lot of people. “This is an outrage! I come here every Tuesday, and every time I get an extra sauce. I have never been charged for it before.” Rather than being happy about getting the extra sauce for free the first five times, they’re upset about not getting it for free the sixth time. However, if the McDonald’s employee were to let you know, “Hey, we’re supposed to charge for extra sauce, but I’ll let you have it for free this time,” then you’re less likely to feel like you’re being unjustly charged when you’re eventually asked to pay.

The same philosophy can be applied to our software development projects. When the customer makes that first seemingly innocuous, out-of-scope request, let them know that you’re doing them a little favor. “This request is out of scope, but I can see where it would be valuable. I’ll discuss this with the team to see if we can fit it in.” If you decide to do it, be sure to let them know that you’re making an exception this time. Finally, document that you gave them some “extra sauce” so that when/if you need to push back on a request, you can show them everything they’ve already gotten for “free.”

Getting back to the McNugget sauce analogy, some folks would still probably be upset about being made to pay even when they’ve been notified that they should be charged for the sauce they’re getting for free. “I know it’s not supposed to be free, but this is the first time I’ve ever been asked to pay. Get me the manager!” In response to that, I’d say an equally valid takeaway from this article is, “Do not give away [too much|any] extra sauce for free.”

Finding Time to Innovate

Innovation is the backbone of any software development effort. If you aren’t doing something new, what’s the point? Without new ideas, you’ll never be first, you’ll never have something that your competitors don’t, and you will never be the best.

I think most people would agree with these statements when talking about a software company or product, but I’m actually talking about developers. You–the developer–need to constantly explore new ideas and learn new skills. Doing things you’ve always done the way you’ve always done them will likely never result in anything more than marginally better than what you have now. (Hey, more = better, right?) In other words, you will need to do new things in new ways in order to produce something significantly better than what you have now.

This is where things get a little less straightforward. How do you learn to do things you haven’t done in ways you haven’t done them before? In my opinion, it’s all about exploration and experimentation. When I read an article about a new tool or language feature, I’ll spend some time playing around with it. I don’t necessarily have a use in mind; I just want to see what it’s about. The result over time is that I have a whole host of things I’ve messed around with that are implementation-detail candidates on future projects. Additionally, when discussing new projects, I can say things like, “This is useful, but it would be really cool if we added X. Here’s how we can do that.”

We can all agree that innovation is essential, and it’s important for developers to spend time learning and exploring to help with the innovating. There are only so many hours in the day, though, and you’ve probably got other, more important things to work on. You’d love to spend time trying new things, but your boss isn’t going let you have free time to do that. After all, there’s money to be made! So what can you do?

I work for a somewhat old-school software company. The senior management overseeing development isn’t likely to institute 20% time any time soon. They aren’t going to designate a percentage of hours as play time, but that doesn’t mean that creativity is forbidden or frowned upon. It just means you have to find the time yourself. I’d venture to say that most software developers are salaried employees obligated to 40 hours per week but expected to work more. What if you spend just one hour each day learning something new? You’ll probably still be giving 40+ hours of effort to the “actual work,” but you’ll also be learning new things that interest you. Fast math shows us that 5 hours represents 11% of a 45-hour week so, by taking 1 hour each day you effectively create “10% time” for yourself.  If one hour is too much time for you, take 30 minutes, or do it every other day. Take the time and stick it on the end of your lunch hour if you need a bigger block.

By allocating “you time” and spending it, you’re going to grow professionally, and that benefits both you and your employer. You’ll be better equipped to tackle complex problems in the future, and you’ll have fresh ideas for how to solve old problems. You’ll also have increased job satisfaction because you get to work on things that interest you in addition to your regular assignments. I believe it’s a true win-win scenario. So stop worrying about the hours you’re “given,” and go learn something!

Unit Testing Stored Procedure Calls with Rhino Mocks

Database stored procedure calls are one of the trickiest things to unit test, and there are many different approaches that can be taken. My team has run the gamut: test DBs that rollback with each run, no testing for direct data access functions (!), virtual functions w/ partial mocks (see here).

The latest approach that I’ve been using is much more straightforward and feels like a more natural use of Rhino Mocks. Let’s look at some examples of how to test some common database stored procedure tasks. (Note that these examples assume use of the Microsoft Enterprise Library.)

Create a mockable Database

The primary challenge that I’ve found with testing database code is that Microsoft.Practices.EnterpriseLibrary.Data.Database isn’t mock-friendly. However, the other “pieces” such as DbCommand and DbCommandParameterCollection are very easy to work with. So, we can solve the Database problem by creating a simple wrapper (Important! Note that the methods have the virtual keyword, which will allow them to be overridden.):

public class DatabaseWrapper
{
    private Database _database;
    private Database Database
    {
        get { return _database = _database ?? DatabaseFactory.CreateDatabase(); }
        set { _database = value; }
    }

    public virtual DbCommand GetStoredProcCommand(string storedProcedureName)
    {
        return Database.GetStoredProcCommand(storedProcedureName);
    }

    public virtual void DiscoverParameters(DbCommand command)
    {
        Database.DiscoverParameters(command);
    }
}

Executing a stored procedure

Now that we are able to mock the database object, we can write some useful tests. Let’s say you want to execute a stored procedure named “MyStoredProcedure,” and you want to write a test to verify that your code handles an exception thrown when it’s executed. That’s very easy!

Here’s my class with the function I want to test:

public class MyDataAccess
{
    public DatabaseWrapper Database { get; set; }
    public Thingy GetThingy()
    {
        Thingy thingy = null;
        try
        {
            var dbCommand = Database.GetStoredProcCommand("MyStoredProcedure");
            Database.DiscoverParameters(dbCommand);
            var result = dbCommand.ExecuteNonQuery();
            // populate thingy
        }
        catch (Exception ex)
        {
            // handle exception
        }
        return thingy;
    }
}

And here’s my test that will throw an exception when the stored procedure is executed. I create my DatabaseWrapper as a PartialMock, allowing me to override its methods.

[TestMethod]
public void GetThingyHandlesException()
{
    // Arrange
    var target = new MyDataAccess();
    var mockDatabase = MockRepository.GeneratePartialMock<DatabaseWrapper>();
    target.Database = mockDatabase;

    // mock Database
    const string storedProc = "MyStoredProcedure";
    var mockDbCommand = MockRepository.GenerateMock<DbCommand>();
    mockDatabase.Expect(x => x.GetStoredProcCommand(storedProc))
        .Return(mockDbCommand);
    mockDatabase.Expect(x => x.DiscoverParameters(mockDbCommand));
    
    // mock DbCommand
    var ex = new Exception("Oh noes!");
    mockDbCommand.Expect(x => x.ExecuteNonQuery())
        .Throw(ex);

    // Act
    var actual = target.GetThingy();

    // Assert
    mockDatabase.VerifyAllExpectations();
    mockDbCommand.VerifyAllExpectations();
    Assert.IsNull(actual);
}

Setting input parameters

Need to set some input parameters? No problem!

dbCommand.Parameters["@id"].Value = id;

And, in your test, you add this:

var mockParams = MockRepository.GenerateMock<DbParameterCollection>();
var mockParam = MockRepository.GenerateMock<DbParameter>();

mockDbCommand.Expect(x => x.Parameters).Return(mockParams);

mockParams.Expect(x => x["@id"]).Return(mockParam);

const int id = 123;
mockParam.Expect(x => x.Value = id);

mockParams.VerifyAllExpectations();
mockParam.VerifyAllExpectations();

Reading output parameters

How about output parameters?

thingy.Value = dbCommand.Parameters["@Value"].Value as string;

Add the additional mocks and assertions:

var mockOutParam = MockRepository.GenerateMock<DbParameter>();

mockParams.Expect(x => x["@Value"]).Return(mockOutParam);

const string value = "MyValue";
mockOutParam.Expect(x => x.Value).Return(value);

mockParams.VerifyAllExpectations();
mockOutParam.VerifyAllExpectations();
Assert.AreEqual(value, actual.Value);

Working with sets of parameters

When you have more than a few parameters to work with, the unit test code can get quite lengthy. I like to keep it clean by extracting the duplicated logic into a separate function, like so:

var paramsToVerify = new List<DbParameter>();
mockParams.Expect(x => x["@whammyparammy"])
    .Return(MockParameter<int>(paramsToVerify));

My function allows you to specify and verify the type of each parameter, but you could easily modify it to expect a specific value.

private static DbParameter MockParameter<T>(List<DbParameter> paramsCollection)
{
    // set Expect with Arg<T>.Is.TypeOf to force the specific type
    var mockParam = MockRepository.GenerateMock<DbParameter>();
    mockParam.Expect(x => x.Value = Arg<T>.Is.TypeOf);

    if (paramsCollection != null)
        paramsCollection.Add(mockParam);

    return mockParam;
}

I keep the parameters in a list so I can verify them during my assertions.

paramsToVerify.ForEach(x => x.VerifyAllExpectations());

Eight Qualities of Remarkable Emloyees

Inc.com is running a great article by Jeff Haden titled Eight Qualities of Remarkable Employees. The article discusses eight non-tangible behaviors exhibited by the best of the best. These qualities all transcend industry, but there were a few that I felt were particularly true for software development.

They ignore job descriptions

There are many external factors that can influence a software project, and any one of them can roadblock the whole thing. New requirements, unexpected challenges, verification, and deployment issues all have the ability to derail your timeline, and it will often be someone else’s official responsibility to deal with the problem. Waiting for somebody else costs you valuable time and can ultimately lead to missed deadlines or failure. Cut out the middle-men, do what needs to be done, and enjoy success.

(This seems obvious, but I’m going to say it anyway: be aware of the politics of your actions. Preventing a distraction: good; doing someone else’s job: bad.)

They like to prove others wrong

If you’ve got a great idea that others don’t believe in, there are two options: let them go down what you believe to be an incorrect or inferior path, or prove them wrong. When you set out to prove them wrong, you may find that you were actually wrong. (*gasp* I know–not likely, right?) That’s still a win, though, because you (hopefully!) learned from it. If you’re right, you’ll help steer a project toward an optimal solution and gain credibility with your team.

I think healthy competition also falls into this category. If you have individuals competing with each other to find an optimal solution, you’re more likely to find it than if you have a single person trying to accomplish the same thing. Each person is likely to come up with a solution that they feel is the best, and the way to “win” is to prove its the best to their peers.

They’re always fiddling

Tinkering is SO important to software developers. It’s how you practice and hone your craft. It’s how your learn new things. Evolving your skillset and tools allows you to be more creative and innovative with your solutions, which further energizes the team.

Make Your Job Obsolete

A long time ago, I read a book by Chad Fowler titled The Passionate Programmer: Creating a Remarkable Career in Software Development. This is a great book that I’d recommend to anybody getting started in software development. It’s full of great tips and ideas like trying to be the worst on your team (surround yourself by greatness), the importance of practice, and striving to be a little better every single day.

One of the concepts that really resonated with me is making it a goal to make whatever position you’re currently in obsolete. With a larger software company, it’s easy to get your hands into a lot of different projects. It’s also easy to become the person with specialized knowledge on specific topics. There’s a feeling of security that comes along with that–they can’t get rid of me; nobody else knows this–but it also makes it harder for you to move forward. I fell into this trap myself a few years ago. There was nobody on the bench to replace me so that I could move on to new and different challenges, and it took some time to get myself out of that position.

Keeping the goal of obsoleting your job in mind day-to-day helps you accomplish two major things: your tasks get easier and you stay available for whatever’s next. And, one of the amazing things about being a software developer is that you have the power to do this through software! The key is identifying processes that can be automated and then mustering up the motivation to follow through and execute.

So what processes can/should be automated? This will be different for everybody and largely depends on your typical tasks. Here are some examples I’ve encountered:

  • Anything that involves cutting and pasting
  • Things that are run on an interval (e.g., daily/hourly/weekly reports)
  • Complex data entry tasks (i.e., create an application to simplify the process)
  • Abused spreadsheets (spreadsheets that are modified and emailed each day can be replaced with web portals with databases that have entry and reporting)
  • Utility-type or out-of-application SQL scripts

Your imagination is the limit. Dream it, create it, and share it. If you do a great job, your managers and co-workers will thank you!