Per prima cosa motiverò rapidamente la domanda con il mio caso d'uso. La mia libreria deve esporre un classificatore di eccezioni Java a un framework a cui si collega. Per esempio:Cicli in eccezioni concatenate
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;
}
A volte, e per ragioni fuori dal mio controllo, l'eccezione passato è un wrapper per quello che mi interessa quindi voglio cercare la catena di causa per esso. La mia idea iniziale era:
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());
}
Purtroppo, questo potrebbe tradursi in una ricorsione infinita se l'eccezione passata ha un ciclo nella sua catena causale. È altamente improbabile che venga inoltrata un'eccezione di questo tipo e si potrebbe sostenere che si tratta di un errore in un altro punto del sistema se viene creata un'eccezione di questo tipo, ma sono molto a disagio nell'avere la possibilità che la mia libreria sia responsabile di una produzione interruzione se succede. L'API di Throwable e javadoc non proibiscono esplicitamente questa possibilità al di là dell'idea che i cicli siano intrinsecamente privi di senso in una catena causale.
Ho notato che Guava ha un metodo @Beta per estrarre la catena causale, Throwables.getCausalChain, ma la sua implementazione è suscettibile allo stesso problema - finirà per lanciare un OOME.
Ho intenzione di utilizzare un identity hash set per rilevare il ciclo e mitigare il rischio, ma volevo sentire come gli altri vedono questo problema. Pensi che io sia troppo difensivo? Cosa faresti?