Handle All Else Conditions

CategorySillyAdvice?

If there is a conditional statement:

    if (condition) {
    }
    else {
        // Handle it
    }
Here, even if there is no chance that the else condition will be executed in the near future, handle it nevertheless. Even if the only thing you do is to log. In case you have nothing to do, just add a comment "Do nothing" just to tell the reader that this condition was thought about. I have personally found this very effective, especially if it's logged. Then I would know that the condition I had thought "could never happen" did really happen after some time (because of a break in the flow). -- VhIndukumar

If the else condition has no chance to be executed, why would you write the if in the first place?

You wouldn't. The problem is, sometimes the right thing to do in the else part is nothing.

    if (broken)
        fix(it);
    else
        don'tfix(it);   /// whazzup?

Like this?
    if (broken) {
      if (brokenThisWay)
        fixThisWay(it);
      else if (brokenOtherWay)
        fixOtherWay(it);
      else if (brokenAnotherWay)
        fixAnotherWay(it);
      else
        throw new Exception("I can not fixit."); // instead of letting it through
    }
Business conditions are not always in single flow (They are not so simple). They can have multiple flows. You can say that the above conditions can be overcome by using correct design (to avoid if-else conditions). But how many people are not using if-else blocks in their daily code? If you consider bugs as a result of un-handled flow, you can understand this. Many such problems arise while maintaining legacy code.


This seems like a very rigid requirement, and it seems like it would lead to a lot of necessary line-noise code. What if I were writing a loop that iterated through an array, counting the number of zeros:

 int count = 0;
 for (int i = 0; i < array.size; i++) {
     if (array[i] == 0) {
         count++;
     }
 }
What would be the point of putting an else in that if statement? It would be line-noise, distracting from the real purpose of the code.

The title is a little misguiding. The content speaks about the else condition you aren't aware how to handle, not about the else condition that is well expected. At least, this is how I understood it.


I was speaking in the context of else conditions that have fairly less chance of getting executed. A typical scenario is checking for some business logic specific conditions. Usually it happens that we take into consideration many flows in business logic and leave out some flows because they cannot happen under the current business requirements. But later we find that a change in someother place leads to this condition not being handled and we end up in NullPointerException being thrown.

 public AccountID credit(Customer cust) {
   AccountID accId = null;
   if (cust.hasCreditCard()) {
      // Do something
   }
   return accId;
 }
Here (this code is not proper but it serves the purpose), suppose the business requirement stated at that time that customer should have a credit card to proceed. Later, it might be decided that debit cards are also welcome. If the else condition had been handled here, we would have known where [?] all we have left out. You are right that in the case of loops, such as the example given above, the else case is useless. -- VhIndukumar

Why not just something like

 public AccountID credit(Customer cust) {
    assert(cust.hasCreditCard());
    AccountID accId = null;
    // Do something
    return accId;
 }
and some exception handling code at the level where the transaction starts?

That's a good example. We've seen a lot of code recently from one of our suppliers where there are "missing" else clauses. They are missing because, it turns out, certain undocumented assumptions about the state of the object, about the method's contract, are being made. Redundant else's should be omitted, but there should be sufficient clues in the code such that the reader feels confident that any elses that are omitted really would be redundant if included.


Here's an interesting idiom I've come across:

 if (...) {
 // do nothing
 } else {
 invokeMethod();
 }

-- ChanningWalton

That might be an indication that the writer expect the comment gets replaced by code in future changes.

(Actually, it is good advice to always code an else clause. Why? To ensure that both possibilities have been considered, and that doing nothing is the appropriate strategy for the alternate case. It works! Try it for a while.) -- JimRussell

Some languages, such as CommonLisp and PerlLanguage, have "when" and "unless" control structures / clauses / whatever. Though the language designers probably considered them mere conveniences, they are also good ways to express this idiom, and encourage new programmers to use it. -- DanielKnapp

I sometimes use this idiom in Java code, when the code in the "else" clause is meant to handle an "exceptional" case. I guess I try to put the "main case" behaviour in the if-then part and the "exceptional case" behaviour in the else part--even if nothing needs to be done in the "main case". I always think twice when I use this idiom, and try to only do it if the resulting code seems clearer/easier to read.

I frequently include empty if or else clauses, in order to make the logic easier to follow. Include a comment explaining why it ought to be empty. Or better yet, use an assertion to explain it.

    if (frequency)
      {
        if (! sound) sound = new sound_t;
        sound.frequency(frequency);
      }
    else if (sound)
      {
        delete sound;
        usage_exit("You must specify a frequency if you specify a sound.");
      }
    else
      {
        assert(!frequency && !sound);
      }


One of the more common uses of if statements is for guard clauses. The advice above should not apply to this type of usage.


This same practice is also useful for switch blocks where all "possible" cases are handled explicitly and by default there is nothing to do.

The general guidance I have heard for switch blocks is to explicitly code all cases rather than relying on default. This is mostly a clarity and searching issue. A global search for a condition code will not find operations that are cavered by default. When reading code (and updating code), it is nice to know a condition was explicitly reviewed and handled and was not overlooked and channeled into the default clause.

I think that depends on the context. The 'default' in a switch should really mean default and not 'the last case we need to handle'. If foreseen cases are 'a', 'b' and 'c', do not use:

  switch (id){
    case 'a':
      doSomething();
      break;
    case 'b':
      doSomethingElse();
      break;
    default:
      doSomethingDifferentAllTogether();
      break;
  }
...but use a case 'c' and use the default to report that an unexpected value was found. OTOH, if the expected values are 0, 1, or any number bigger then 1, using a default for that last option is perfectly acceptable.


EditText of this page (last edited February 14, 2005) or FindPage with title or text search