Friday, January 18, 2008

Debug.Fail

Formerly I thought why should we use Debug.Fail and not to use exception throwing? About a year ago I thought out the case where Debug.Fail will be better than exception throwing. But... I didn't write it down so I've forgotten it :(
But now I want to note an another case:
If we use, for example Abstract Factory of Factory Method we could use Debug.Fail.
Consider the code (it's just a sample to demonstrate one practice not all!):



public IReporter GetStrategy(Type entityType)
        {
            if (entityType == typeof (DictionaryEntity))
            {
                return SimpleMenuStrategy();
            }
            else if (entityType == typeof (ProgramEntity))
            {
                return ExtendedMenuStrategy();
            }
            else
            {
                throw new ArgumentException("Unknown type of entity" + entityType, "entityType");
            }
        }

Than you add some others entities, quantity of them grows quickly. One day (usually it happens right before the build :) ) you add one more entity type and forget to define strategy for it. Oh, damn! Exception is generated. Not good solutions, especially if the function was missed by tester and client will see the exception message.
So, let's rewrite the code:



public IReporter GetStrategy(Type entityType)
        {
            if (entityType == typeof (DictionaryEntity))
            {
                return SimpleMenuStrategy();
            }
            else if (entityType == typeof (ProgramEntity))
            {
                return ExtendedMenuStrategy();
            }
            else
            {
                Debug.Fail("Unknown type of entity" + entityType);
                return SimpleMenuStrategy();
            }
        }

Now we get an exception only during Debug time no runtime on the customer's side. We just return a strategy that can perform only the minimum set of functionality. May be it's even will be good enough to customer and won't turn into the fatal error that should be fixed ASAP (e.g. minimal menu will contain "Open" and "Delete" items, but won't contain "Call this person" which absence is not critical for customer for a time).

Yes, it's a fake code and a little far-fetched solution. But it works and I think works better in the second case than in first one. And general rule: call Debug.Fail where the developer's mistake that you should cover with some solution, and throw exception in other cases.

No comments: