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
Post a Comment