What is a good way to pass useful state information to an exception in Java?

前端 未结 11 1892
说谎
说谎 2021-02-04 06:23

I noticed some confusion initially with my question. I\'m not asking about how to configure a logger nor how to use a logger properly, but rather how to capture all of the infor

11条回答
  •  庸人自扰
    2021-02-04 06:56

    Another good logging API is SLF4J. It can be configured to also intercept log APIs for Log4J, Java Util Logging, and Jakarta Commons Logging. And it can also be configured to use various logging implementations, including Log4J, Logback, Java Util Logging, and one or two others. This gives it enormous flexibility. It was developed by the author of Log4J to be its successor.

    Of relevance to this question, the SLF4J API has a mechanism to concatenate string valued expressions into a log message. The following calls are equivalent, but the second is about 30x faster to process if you're not outputting debug level messages, since the concatenation is avoided:

    logger.debug("The new entry is " + entry + ".");
    logger.debug("The new entry is {}.", entry);
    

    There's a two argument version too:

    logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
    

    And for more than two you can pass in an array of Object like this:

    logger.debug("Value {} was inserted between {} and {}.", 
                 new Object[] {newVal, below, above});
    

    This is a nice terse format that eliminates clutter.

    Example source is from the SLF4J FAQ.

    Edit: Here's a possible refactoring of your example:

    try {
        doSomething(someObject.getValue());
    }
    catch (BadThingsHappenException bthe) {
      throw new UnhandledException(
        MessageFormatter.format("An error occurred when setting value. [value={}]", 
                                  someObject.getValue()), 
        bthe);
    }
    

    Or if this pattern occurs more than a few places you could write a set of static methods that capture the commonality, something like:

    try {
        doSomething(someObject.getValue());
    }
    catch (BadThingsHappenException bthe) {
        throwFormattedException(logger, bthe,
                                "An error occurred when setting value. [value={}]", 
                                someObject.getValue()));
    }
    

    and of course the method would also put the formatted message out on the logger for you.

提交回复
热议问题