Assume that this piece of code is in 20 places and always the same
try {
// do something
} catch (FirstException e) {
// log it
} catch (SecondException e) {
// log it
}
Wouldn't be better to use something like this or instanceof
is not good solution?
try {
// do something
} catch(Exception e) {
logException(e);
}
void logException(Exception e) {
if (e instanceof FirstException) {
// log it
} else if (e instanceof SecondException) {
// log it differently
} else {
// do something with other exception
}
}
The only thing that I really hate about the solution is catching Exception
which is definitelly not the best way... Is there any better way?
catch (FirstException1 | SecondException | ...)
catch (Exception e)
—you do want to log all exceptions, don't you? I would in fact advise catch (Throwable t)
because OutOfMemoryError
s and StackOverflowError
s also want to be logged.An advice from many years of experience with logging exceptions is to log them all the same way. The exception message is enough as human-readable text, and what the developer really needs for debugging is the stack trace.
Just be careful about one thing: never catch exceptions too early: catch them at a single place for the whole application, the so-called exception barrier—it is at the level where you enter and exit a unit of work.
If checked exceptions are giving you trouble at the lower level, wrap them into RuntimeException
:
try {
...
}
catch (RuntimeException e) {throw e;}
catch (Exception e) {throw new RuntimeException(e);}
Only if you know precisely and in advance that there is an exception which has business-level meaning to your application, and will not abort the current unit of work, but redirect its flow, is it appropriate to catch that exception at a lower level. In practice such exceptions are rare compared to the totality of all possible exceptions thrown by the application code.