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 }