Never, ever, swallow your stack trace.

Tags:

I came across this kind of exception handling code.

import java.util.Observable;
import java.util.Observer;

public class Framework extends Observable {

  public void SendMessage(String msg) {
    setChanged();
    try {
      notifyObservers(msg);
    } catch (RuntimeException re) {
      throw new RuntimeException("Something bad happend.");
    }
  }

  public static void main(String[] args) {
    Framework f = new Framework();
    f.addObserver(new Observer() {
      @Override
      public void update(Observable o, Object arg) {
        System.out.println("I am fine: " + arg.toString());
      }
    });
    f.SendMessage("hello world");
  }
}

This is pretty common pattern. Right? You create a list of several instances and iterate over them to do something. Actually, that’s the beautiful pattern commonly used.

But, the code actually has a pitfall. Look at the error handling part. Can you identify it?

try {
  notifyObservers(msg);
} catch(RuntimeException re) {
  throw new RuntimeException("Something bad happend."); 
}

At first glance, this looks fine. It’s trying to tell something to the user. It’s not even swallowing the exception. But that’s not all for the framework developer. What happens if I add an innocent observer but got some error?

  public static void main(String[] args) {
    Framework f = new Framework();
    f.addObserver(new Observer() {
      @Override
      public void update(Observable o, Object arg) {
        System.out.println("I am fine: " + arg.toString());
      }
    });
    f.addObserver(new Observer() {
      @Override
      public void update(Observable o, Object arg) {
        throw new RuntimeException("I got an error: " + arg.toString());
      }
    });
    f.SendMessage("hello world");
  }

Now the code spits out this:

Exception in thread “main” java.lang.RuntimeException: Something bad happend.
at Framework.SendMessage(Framework.java:11)
at Framework.main(Framework.java:29)

Seriously, that’s all I get. If this happens, I’m left with no clue but something went wrong.

Please do not swallow not just your exception but also your stack trace. How can I believe that all other observers are fine but it’s just my fault without any proof?

Keep the stack trace:

try {
    notifyObservers(msg);
} catch (RuntimeException re) {
    throw new RuntimeException("Something bad happend.", re);
}

Now I get this awesome trace:

Exception in thread “main” java.lang.RuntimeException: Something bad happend.
at Framework.SendMessage(Framework.java:11)
at Framework.main(Framework.java:29)
Caused by: java.lang.RuntimeException: I got an error: hello world
at Framework$2.update(Framework.java:26)
at java.util.Observable.notifyObservers(Unknown Source)
at Framework.SendMessage(Framework.java:9)
… 1 more