View Javadoc
1   package com.acumenvelocity.ath.common.exception;
2   
3   import org.slf4j.helpers.MessageFormatter;
4   
5   import com.acumenvelocity.ath.common.Log;
6   
7   /**
8    * Base exception class for all ATH (AcumenTranslation Hub) framework exceptions.
9    * This class provides structured exception handling with integrated logging capabilities.
10   * All custom exceptions in the ATH framework should extend this class.
11   * 
12   * <p>
13   * <b>Key Features:</b>
14   * </p>
15   * <ul>
16   * <li>Integrated logging with exception throwing</li>
17   * <li>Message formatting using SLF4J pattern</li>
18   * <li>Support for exception chaining</li>
19   * <li>Thread-safe exception creation</li>
20   * </ul>
21   * 
22   * @author Acumen Velocity
23   * @version 1.0
24   * @since 1.0
25   */
26  public class AthException extends Exception {
27  
28    private static final long serialVersionUID = 4068512805591697913L;
29  
30    /**
31     * Creates an empty AthException object.
32     * <p>
33     * <b>Note:</b> This constructor is private to enforce the use of static
34     * {@code logAndThrow()} methods for consistent exception handling.
35     * </p>
36     */
37    // XXX Always use static logAndThrow() methods for consistent exception handling
38    private AthException() {
39      super();
40    }
41  
42    /**
43     * Creates a new AthException object with a given message.
44     *
45     * @param message the descriptive text of the exception message
46     */
47    private AthException(String message) {
48      super(message);
49    }
50  
51    /**
52     * Creates a new AthException object with a formatted message.
53     * Uses SLF4J-style message formatting with placeholders.
54     *
55     * @param format the message format string with {} placeholders
56     * @param args   the arguments to substitute into the format string
57     */
58    private AthException(String format, Object... args) {
59      super(MessageFormatter.arrayFormat(format, args).getMessage());
60    }
61  
62    /**
63     * Creates a new AthException object with a formatted message and cause.
64     *
65     * @param cause  the underlying exception that caused this exception
66     * @param format the message format string with {} placeholders
67     * @param args   the arguments to substitute into the format string
68     */
69    private AthException(Throwable cause, String format, Object... args) {
70      super(MessageFormatter.arrayFormat(format, args).getMessage(), cause);
71    }
72  
73    /**
74     * Creates a new AthException object with a given parent exception cause.
75     *
76     * @param cause the underlying exception that caused this exception
77     */
78    private AthException(Throwable cause) {
79      super(cause);
80    }
81  
82    /**
83     * Creates a new AthException object with a given message and parent exception cause.
84     *
85     * @param message the descriptive text of the exception message
86     * @param cause   the underlying exception that caused this exception
87     */
88    private AthException(Throwable cause, String message) {
89      super(message, cause);
90    }
91  
92    /**
93     * Logs an error message and throws an AthException.
94     * <p>
95     * This method provides a consistent pattern for error handling by combining
96     * logging and exception throwing in a single operation.
97     * </p>
98     *
99     * @param loggingClass the class where the error occurred (for logging context)
100    * @param format       the error message format string with {} placeholders
101    * @param arguments    the arguments to substitute into the format string
102    * @throws AthException always throws an AthException after logging
103    */
104   public static void logAndThrow(Class<?> loggingClass,
105       String format, Object... arguments) throws AthException {
106     // Log the error with appropriate context
107     Log.error(loggingClass, format, arguments);
108     // Throw the exception with formatted message
109     throw new AthException(format, arguments);
110   }
111 
112   /**
113    * Logs an error message with cause and throws an AthException.
114    *
115    * @param loggingClass the class where the error occurred (for logging context)
116    * @param cause        the underlying exception that caused this error
117    * @param format       the error message format string with {} placeholders
118    * @param arguments    the arguments to substitute into the format string
119    * @throws AthException always throws an AthException after logging
120    */
121   public static void logAndThrow(Class<?> loggingClass, Throwable cause,
122       String format, Object... arguments) throws AthException {
123     // Log the error with cause and context
124     Log.error(loggingClass, cause, format, arguments);
125     // Throw the exception with formatted message (note: cause is not included in this overload)
126     throw new AthException(format, arguments);
127   }
128 
129   /**
130    * Logs an error with just the cause and throws an AthException.
131    *
132    * @param loggingClass the class where the error occurred (for logging context)
133    * @param cause        the underlying exception that caused this error
134    * @throws AthException always throws an AthException after logging
135    */
136   public static void logAndThrow(Class<?> loggingClass, Throwable cause)
137       throws AthException {
138     // Log the error with the cause's string representation
139     Log.error(loggingClass, cause, cause.toString());
140     // Throw the exception with the cause included
141     throw new AthException(cause, cause.toString());
142   }
143 }