How come you cannot catch Code Contract exceptions?

This is deliberate – although a slight pain for testing.

The point is that in production code you should never want to catch a contract exception; it indicates a bug in your code, so you shouldn’t be expecting that any more than arbitrary unexpected exceptions which you may want to catch right at the top of your call stack so you can move onto the next request. Basically you shouldn’t view contract exceptions as ones which can be “handled” as such.

Now, for testing that’s a pain… but do you really want to test your contracts anyway? Isn’t that a bit like testing that the compiler stops you from passing in a string to a method which has an int parameter? You’ve declared the contract, it can be documented appropriately, and enforced appropriately (based on settings, anyway).

If you do want to test contract exceptions, you can either catch a bare Exception in the test and check its full name, or you can mess around with the Contract.ContractFailed event. I would expect unit testing frameworks to have built-in support for this over time – but it’ll take a little while to get there. In the meantime you probably want to have a utility method to expect a contract violation. One possible implementation:

const string ContractExceptionName =
    "System.Diagnostics.Contracts.__ContractsRuntime.ContractException";

public static void ExpectContractFailure(Action action)
{
    try
    {
        action();
        Assert.Fail("Expected contract failure");
    }
    catch (Exception e)
    {
        if (e.GetType().FullName != ContractExceptionName)
        {
            throw;
        }
        // Correct exception was thrown. Fine.
    }
}

Leave a Comment