[Yanel-dev] exceptions, logging and related best practices (was: Re:
[Yanel-commits] rev
48212 - public/yanel/trunk/src/contributions/resources/policymanager/src/java/org/wyona/yanel/impl/resources/policymanager)
Guillaume Déflache
guillaume.deflache at wyona.com
Mon Mar 22 18:58:46 CET 2010
Michael Wechner schrieb:
> Dear Guillaume
>
> guillaume at wyona.com wrote:
>> return sb.toString();
>> } catch(Exception e) {
>> - log.error(e, e);
>> + log.error(e.getMessage(), e);
>>
>
> Why are you changing these?
Because for some reason I believed that toString() called
getLocalizedMessage() by default (that would have produced French
messages if your JVM locale was set to French, which believe me, are
almost uncomprehensible even to French people compared to the English
ones!).
But after rereading the Javadoc for Throwable it seems I was completely
mistaken, so I won't do that anymore from now on!
Thanks for noticing it!
> I am afraid this will lead to a commit war, because I will change it
> back shortly ;-)
Indeed toString() seems to provide additional details and to call
getMessage() by default:
http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html#toString%28%29
And it's also nicely shorter and more readable if a little odd-looking
at 1st glance.
> So, let's discuss it first and write down some rules how we want to
> handle it.
I'll start then (notes: T extends Throwable, what is applicable to
org.apache.log4j.Logger#error(Object, Throwable) calls is also
applicable to other logging methods with similar signatures):
0) vital and always applicable: do not lose stacktraces
0.0) for ignorable exceptions never do:
} catch (Exception e) {
// empty catch block
}
...but instead do at least the following:
} catch (Exception e) {
if (logger.isDebugEnabled()) logger.debug("swallowed exception "+e, e);
}
...because it won't hurt performance much, whereas throwing a lot of
exceptions and not knowing about it will!
0.1) never do logger.error(throwable) but do logger.error(throwable,
throwable) because else the original stacktrace gets lost ...but not
logger.error(throwable.getMessage(), throwable) as explained above
1) very important and almost always applicable: do not "over-log" exceptions
1.0) do not log _and_ throw the same exception: do not do:
} catch (Exception e) {
log.error(e, e);
throw new RuntimeException(e, e);
}
...but do:
} catch (Exception e) {
throw new RuntimeException(e, e);
}
...or maybe:
} catch (Exception e) {
log.error(e, e); // for the administrator and programmer
eventuallyUserFacingErrorReportMechanism.addError(friendlyErrorMessage/*,
e*/); // for the user (and optionally priviledged users may be allowed
to see the exception and related stacktrace)
}
...except at the highest level when you are sure no one will log the
exception further up, e.g.:
- in the 'main' method
- in a servlet in the highest-level protected methods inherited from
HttpServlet, e.g. 'service', 'destroy', etc.
- in the 'run' method of a Thread
...else your stacktraces will get so big they will get truncated!
1.1) avoid rewrapping exceptions that do not need to be rewrapped
because they are already of the needed type: e.g. do not do:
} catch (Exception e) {
throw new RuntimeException(e);
}
...but rather do:
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
... else your stacktraces will get bigger (see above)
That's all I have in mind for now.
HTH,
Guillaume
More information about the Yanel-development
mailing list