Załóżmy, że obsługuję FooException
i BarException
. Załóżmy, że oba są niezaznaczonymi wyjątkami.Jak uzyskać poprawnie powiązany ślad stosu dla wyjątków zgłaszanych podczas obsługi innych wyjątków?
Co chcę zobaczyć w stacktrace jest:
com.bar.BarException: Bar Message
at com.baz.BazCode(BazCode.java:123)
...
Caused by: com.foo.FooException: Foo Message
at com.baz.BazCode(BazCode.java:321)
....
Caused by: ...
Jednak domyślnie cały zapis FooException
zostaną usunięte z stacktrace. Na przykład:
// In a class written by me
/**
* ...
* @throws FooException if foo happens
* @throws BarException if bar happens
*/
public void upperFrame() {
try {
foo.doSomething();
} catch (FooException foo) {
bar.doSomethingElse();
}
}
// In class Bar (not written by me)
public void doSomethingElse() {
if (someConditionWhichHappensToBeTrueInThisScenario()) {
throw new BarException("Hello Bar World"); // At this point, FooException gets erased from the stack trace
}
}
Jeśli BarException
ma (message, cause)
konstruktora wtedy mogę śledzić raczej surowy rodzaj procesu „instrukcja klonowania”, aby osiągnąć mój cel:
try {
foo.doSomething();
} catch (FooException foo) {
try {
bar.doSomethingElse();
} catch (BarException bar) {
BarException bar2 = new BarException(bar.getMessage(), foo);
bar2.setStackTrace(bar.getStackTrace());
throw bar2;
}
}
Jednak jeśli BarException
nie ma takich konstruktor (np ClassCastException
) to jestem zredukowana do robienia rzeczy tak:
try {
foo.doSomething();
} catch (FooException foo) {
try {
bar.doSomethingElse();
} catch (BarException bar) {
RuntimeException e = new RuntimeException("com.bar.BarException: " + bar.getMessage(), foo);
e.setStackTrace(bar.getStackTrace());
throw e;
}
}
jest to niebezpieczne be powoduje, że e
ma niewłaściwy typ i dlatego może nie być poprawnie obsługiwany przez wyższe ramki.
Czy istnieje sposób "najlepszej praktyki" radzenia sobie z tą sytuacją?
Czy ślad stack'u 'FooException' stracił podczas tworzenia' BarException' z przyczyną Foo? Czy mógłbyś zrobić coś takiego jak 'bar.getCause(). GetStackTrace()'? –
@KaspervandenBerg Edytowałem moje pytanie, aby pokazać, jak 'FooException' ginie. Nie jest związane z żadnym tworzeniem wyjątku z przyczyną, jest to wyjątek generowany przez metodę 'doSomethingElse'. – Kidburla