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

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

    We tend to create our most important application specific runtime exception classes with some special constructors, some constants and a ResourceBundle.

    Example snippet:

     public class MyException extends RuntimeException
     {
        private static final long serialVersionUID = 5224152764776895846L;
    
        private static final ResourceBundle MESSAGES;
        static
        {
            MESSAGES = ResourceBundle.getBundle("....MyExceptionMessages");
        }
    
        public static final String NO_CODE = "unknown";
        public static final String PROBLEMCODEONE = "problemCodeOne";
        public static final String PROBLEMCODETWO = "problemCodeTwo";
        // ... some more self-descriptive problem code constants
    
        private String errorCode = NO_CODE;
        private Object[] parameters = null;
    
        // Define some constructors
    
        public MyException(String errorCode)
        {
            super();
            this.errorCode = errorCode;
        }
    
        public MyException(String errorCode, Object[] parameters)   
        {
            this.errorCode = errorCode;
            this.parameters = parameters;
        }
    
        public MyException(String errorCode, Throwable cause)
        {
            super(cause);
            this.errorCode = errorCode;
        }
    
        public MyException(String errorCode, Object[] parameters, Throwable cause)
        {
            super(cause);
            this.errorCode = errorCode;
            this.parameters = parameters;
        }   
    
        @Override
        public String getLocalizedMessage()
        {
            if (NO_CODE.equals(errorCode))
            {
                return super.getLocalizedMessage();
            }
    
            String msg = MESSAGES.getString(errorCode); 
            if(parameters == null)
            {
                return msg;
            }
            return MessageFormat.format(msg, parameters);
        }
     }
    

    In the properties file we specify the exception descriptions, e.g.:

     problemCodeOne=Simple exception message
     problemCodeTwo=Parameterized exception message for {0} value
    

    Using this approach

    • We can use quite readable and understandable throw clauses (throw new MyException(MyException.PROBLEMCODETWO, new Object[] {parameter}, bthe))
    • The exception messages are "centralized", can easily maintained and "internationalized"

    EDIT: change getMessage to getLocalizedMessage as Elijah suggested.

    EDIT2: Forgot to mention: this approach does not support Locale changing "on-the-fly" but it is intentional (it can be implemented if you need it).

提交回复
热议问题