Brian Harris Brian Harris - 1 year ago 68
Java Question

Cycles in chained exceptions

I'll first quickly motivate the question with my use case.
My library needs to expose a Java exception classifier to a framework which it plugs in to. For example:

enum Classification { FATAL, TRANSIENT, UNKNOWN }

Classification classify(Throwable t) {
if (t instanceof MyTransientException)
return Classification.TRANSIENT;
else if (t instanceof MyFatalException)
return Classification.FATAL;
else
return Classification.UNKNOWN;
}


Sometimes, and for reasons out of my control, the passed exception is a wrapper around the one I'm interested in so I want to search the cause chain for it. My initial idea was:

Classification classify(Throwable t) {
if (t == null)
return Classification.UNKNOWN;

if (t instanceof MyTransientException)
return Classification.TRANSIENT;
else if (t instanceof MyFatalException)
return Classification.FATAL;
else
return classify(t.getCause());
}


Unfortunately, this could result in infinite recursion if the passed exception has a cycle in its causal chain. It's highly unlikely that such an exception will be passed, and an argument could be made that it's an error elsewhere in the system if such an exception is created, but I'm very uncomfortable with having the possibility of my library being responsible for a production outage if it happens. Throwable's API and javadoc do not explicitly forbid this possibility beyond the idea that cycles are inherently nonsensical in a causal chain.

I noticed that Guava has a @Beta method to extract the causal chain, Throwables.getCausalChain, but its implementation is susceptible to the same issue -- it will wind up throwing an OOME.

I'm planning to use an identity hash set to detect the cycle and mitigate the risk, but I wanted to hear how others view this issue. Do you think I'm being overly defensive? What would you do?

Answer Source

It's great that you are being so conscientious. But you don't want to get into the business of manufacturing kevlar boots.

If a user does something that would make even Throwable.printStackTrace go into infinite recursion, that user is beyond help. Don't even worry about this.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download