2011-09-28 11 views
10

Najpierw szybko zmotywuję pytanie w moim przypadku użycia. Moja biblioteka musi ujawnić klasyfikator wyjątków Java do architektury, do której się podłącza. Na przykład:Cykle w przykutych wyjątkach

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; 
} 

Czasem iz powodów z mojej kontroli, przeszły Wyjątkiem jest owinięcie się wokół jednego, który mnie interesuje, więc chcę, aby szukać łańcucha przyczynowo dla niego. Mój początkowy pomysł był następujący:

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()); 
} 

Niestety, może to doprowadzić do nieskończonej rekursji, jeżeli przeszedł wyjątek ma cykl w swoim łańcuchu przyczynowym. Jest bardzo mało prawdopodobne, że taki wyjątek zostanie przekazany, i można by argumentować, że jest to błąd w innym miejscu systemu, jeśli taki wyjątek jest tworzony, ale jestem bardzo niewygodny z powodu możliwości, że moja biblioteka będzie odpowiedzialna za produkcję awaria, jeśli tak się stanie. Interfejs API Throwble'a i javadoc nie zabraniają wyraźnie tej możliwości, wychodząc poza założenie, że cykle są z natury bezsensowne w łańcuchu przyczynowym.

Zauważyłem, że Guava ma metodę @Beta do wyodrębnienia łańcucha przyczynowego, Throwables.getCausalChain, ale jej implementacja jest podatna na ten sam problem - zakończy się rzuceniem OOME.

Mam zamiar użyć identity hash set do wykrycia cyklu i zmniejszenia ryzyka, ale chciałem usłyszeć, jak inni widzą ten problem. Myślisz, że jestem zbyt defensywny? Co byś zrobił?

Odpowiedz

13

To świetnie, że jesteś tak sumienny. Ale nie chcesz dostać się do branży produkcji kevlarowych butów.

Jeśli użytkownik zrobi coś, co spowoduje, że nawet Throwable.printStackTrace przejdzie do nieskończonej rekurencji, ten użytkownik nie będzie mógł uzyskać pomocy. Nawet się tym nie przejmuj.

Powiązane problemy