Reputation: 96471
Ultimately, i'd like to
if (badThingsHappen) {
log the issue
throw exception with description
}
The obvious redundancy here is that often exception description and the message to be logged is (often) the same.
This looks needlessly verbose
if (badThingsHappen) {
logger.error("oh no! not again!");
throw new AppException("oh no! not again!");
}
Declaring temporary String feels wrong
if (badThingsHappen) {
String m = "oh no! not again!";
logger.error(m);
throw new AppException(m);
}
Is it ok to have Exception's constructor handle the logging? Is there a better (cleaner) way?
Upvotes: 8
Views: 5240
Reputation: 2139
I just wrote an error-logging method myself, today (this is used to log errors if they occur in a listener method, so it's also logging the method in which the error occurred and the object in which the listener is implemented to help tracking):
protected void listenerError(String listenerMethodName, Object listener,
RuntimeException e) {
logger.error("Exception while calling " + listenerMethodName
+ " on object " + listener, e);
throw e;
}
I wrote it in the class in question (or the base class, to be exact), because you probably want to use the logger in that class (and all subclasses). Another option would be to create a utility method in a utility class (I would not write an Exception class for it), and provide the logger as parameter:
class ExceptionUtil {
public static error(Exception e, Logger logger) {
logger.error(e);
throw e;
}
}
You can, of course, provide the method and object as params for this method (or an overloaded version of it), as necessary.
Upvotes: 1
Reputation: 50127
You could use a utility method:
public class AppException extends Exception {
public static AppException logAndThrow(Logger logger, String message) throws AppException {
AppException e = new AppException(message);
// log the stack trace as well
logger.error(message, e);
throw e;
}
}
and the use it:
if (badThingsHappen) {
AppException.logAndThrow(logger, "oh no! not again!");
}
Upvotes: 3
Reputation: 15256
Typically when working with Exceptions and logging requirements I include logging support in the Exceptions.
Exceptions typically inherit from a Base Exception class in our project and it has hooks for logging log4j
or other logging utilities.
class Problem extends java.lang.Exception {
private boolean debug=false;
public Problem(String message) {
if(debug) {
logging.exception(message);
/* Maybe a stack trace? */
}
}
}
Upvotes: 1
Reputation: 15990
I usually prefer to log exceptions when I catch them, rather then when I throw them.
This cleans up the logs quite a bit more, and also lets the "client" code handle the exception and information output much more precisely, since the information you want to associate with the exception when logging can be dependent of context.
If you do want to log as soon as it happens, I would build the exception and log it before throwing, something like:
if(badthingshappen){
Exception e = new Exception("holy $%##");
logger.log(e);
throw e;
}
A bit verbose yes... but this is java.
Upvotes: 2