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

前端 未结 11 1991
说谎
说谎 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:55

    Besides your example which declares local fields outside the try block in order to be accessible inside the catch block, one very simple way of handling this is to dump the state of the class out in the Exception using the class's overridden toString method. Granted, this is only useful in Classes that maintain state.

    try {
       setMyValue(someObject.getValue());
       doSomething(getMyValue());
    }
    catch (BadThingsHappenException bthe) {
       // consider this a RuntimeException wrapper class
      throw new UnhandledException(toString(), bthe);
    }
    

    Your toString() would need to be overridden:

    public String toString() {
       return super.toString() + "[myValue: " + getMyValue() +"]";
    }
    

    edit:

    another idea:

    You could maintain state in a ThreadLocal debug context. Suppose you create a class called MyDebugUtils which holds a ThreadLocal that contains a Map per Thread. You allow for static access to this ThreadLocal and maintenance methods (ie, to clear the context when your debugging is finished).

    The interface could be:

    public static void setValue(Object key, Object value)
    public static void clearContext()
    public static String getContextString() 
    

    and in our example:

    try {
       MyDebugUtils.setValue("someObeject.value", someObject.getValue());
       doSomething(someObject.getValue());
    } catch (BadThingsHappenException bthe) {
       // consider this a RuntimeException wrapper class
      throw new UnhandledException(MyDebugUtils.getContextString(), bthe);
    } finally {
      MyDebugUtils.clearContext(); 
    }
    

    There might be some issues that you would want to iron out, such as handling cases where your doSomething method also contains a try/catch/finally set that clears the debug context. This could be handled by allowing for finer granularity in the context Map than just the Thread in the process:

    public static void setValue(Object contextID, Object key, Object value)
    public static void clearContext(Object contextID)
    public static String getContextString(Object contextID)
    

提交回复
热议问题