2014-08-27 12 views
5

W Javie możemy złapać wyjątki pewnego typu:Java zidentyfikować wyjątek właśnie

try{ 
    // Code that does IO like download a file... 
}catch(IOException ioe){ 
    ioe.printStackTrace(); 
    // handle ioe 
}catch(SomeOtherException soe){ 
    // handle soe 
} 

Teraz, nie może być wiele przyczyn do wyjątek, w tym przypadku, IOException może być:

java.io.IOException: Illegal character in path at index..... 

od konkretnej bibliotece lub jakiś inny podobny:

java.io.IOException: Stream closed ... 

Jeśli coś poszło źle z a Stream

Teraz moje pytanie brzmi: jak ustalić, jaki rodzaj zdarzenia się wydarzył?

Jak mogę odróżnić Stream closed i Illegal character in path at index...?

Oczywiście mogę po prostu sprawdzić ciąg komunikatu wyjątku, ale nie sądzę, że jest to najlepszy sposób, ponieważ biblioteka/implementacja może zmienić ciąg wiadomości.

EDIT:

e.getClass() w tym przypadku zwraca java.io.IOException prawie wszystko ...

Chyba biblioteka rzuca swoje własne IOException jednocześnie odrzucając jakąkolwiek oryginalną Exception.

Odpowiedz

7

Fakt printStackTrace drukowane

java.io.IOException: Stream closed ... 
//  ^^^^^^^^^^^ 

i

java.io.IOException: Illegal character in path at index..... 
//  ^^^^^^^^^^^ 

oznacza Exception jest typu IOException. Nie ma bardziej konkretnego podtypu, którego można użyć tutaj.

W tym przypadku nie ma możliwości. Postanowili użyć tego samego typu Exception dla obu (i więcej) z tych powodów. Nie będzie można ich odróżnić za pomocą różnych instrukcji catch. Musisz sprawdzić ich wiadomość.

Jeśli Exception ma cause, musisz sprawdzić, czy istnieje typ odróżniający i ponownie go rzucić. Jeśli masz szczęście, możesz złapać bardziej specyficzny typ Exception.

+2

Wznosiłem cię z powrotem, ponieważ jest to jedyna odpowiedź, która widzi "IOEeception" i wie, że jest to konkretny typ. Nie wiem, dlaczego ktoś miałby cię zająć w pierwszej kolejności ... – tom91136

+0

@HovercraftFullOfEels Metoda 'printStackTrace' zależy od metody' toString'. Implementacja 'Throwable' wypisuje nazwę klasy za pomocą' getClass(). GetName() '. Więc jeśli 'StreamClosedException' nie przesłoni swojego' toString', aby zwrócić nazwę klasy 'IOException', typem konkretnym jest' IOException'. –

+0

@SotiriosDelimanolis: przeprosiny. –

4

można złapać wyjątek odmiennie od IOException to najwyższej hierarchii sub wyjątkami

Od documentation:

java.io.IOException 
    java.io.CharConversionException 
    java.io.EOFException 
    java.io.FileNotFoundException 
    java.io.InterruptedIOException 
    java.io.ObjectStreamException 
     java.io.InvalidClassException 
     java.io.InvalidObjectException 
     java.io.NotActiveException 
     java.io.NotSerializableException 
     java.io.OptionalDataException 
     java.io.StreamCorruptedException 
     java.io.WriteAbortedException 
    java.io.SyncFailedException 
    java.io.UnsupportedEncodingException 
    java.io.UTFDataFormatException 
    java.io.UnsupportedEncodingException 
    java.io.UTFDataFormatException 
+1

Konkretnym typem wyjątków w przypadku OP wydaje się być 'IOException'. Bardziej konkretne podtypy nie pomogą. –

+0

Tak, dokonałem edycji, proszę sprawdzić zaktualizowane pytanie – tom91136

1

Kiedy biblioteka podnosi zbyt ogólny wyjątek (jak się wydaje, ty” wracając tutaj z IOException) niestety nie masz wielu dobrych opcji - w gruncie rzeczy jest to kiepski projekt ze strony biblioteki. W idealnej sytuacji powinieneś zgłosić błąd lub wysłać prośbę o pociągnięcie do biblioteki naruszającej prawa, ale może to nie być możliwe lub wykonalne.

Jednak wszystko nie jest stracone. Przede wszystkim jest możliwe, że biblioteka dostarcza więcej informacji, niż myślisz, włączając w to podstawową IOException podstawową przyczynę poprzez Throwable.getCause(). Jest to niezawodny sposób na dostarczenie bardziej szczegółowych informacji na temat debugowania przy jednoczesnym udostępnianiu pojedynczego Exception do normalnej obsługi. Jeśli ta biblioteka następująco tej praktyki, można zrobić coś takiego:

catch(IOException e) { 
    Throwable cause = e.getCause(); 
    if(cause != null && cause instanceof URISyntaxException) { 
    System.err.println("Bad URI"); 
    } else { 
    System.err.println("Other IOException"); 
    } 
} 

Oczywiście, obracając co jakiś Googling sugeruje to URISyntaxException się z IOException nie jest strasznie dobry projekt w pierwszej kolejności (nieprawidłowy identyfikator URI jest na pewno nie jest to kwestia IO), więc nie zdziwiłbym się, gdyby biblioteka po prostu wywoływała coś w rodzaju throw new IOException(e.getMessage()) i odrzucała oryginał, co oznacza, że ​​niestety wszystko, co musisz zrobić, to wiadomość o wyjątku.

Podobnie jak dla ciebie, parsowanie wyjątków nie jest strasznie świetnym pomysłem. Idealnie powinieneś zawinąć to złe zachowanie w metodę pomocnika, aby móc ją łatwo poprawić po poprawieniu biblioteki i wykryć, czy coś nieoczekiwanego występuje i rozwiązać problem. Rozważmy:

public void doOperation(arguments) throws IOException, URISyntaxException { 
    try { 
    BadLibrary.doOperation(arguments); 
    } catch(IOException e) { 
    if(e.getMessage().startsWith("Illegal character")) { 
     throw new URISyntaxException("Uknown", e.getMessage()); 
    } else if(e.getMessage().startsWith("Stream closed")) { 
     throw e; 
    } else { 
     // note we include the cause here 
     throw new RuntimeException("Unexpected exception from BadLibrary", e); 
    } 
    } 
} 

Dzięki tej kompartmentację trzeba tylko zrobić ten nieprzyjemny czek w jednym miejscu, a może być rozsądnie przekonany, można wykryć nieoczekiwane zmiany w podstawowej bibliotece, zamiast dyskretnie je ignoruje.

Powiązane problemy