SpringBootExceptionHandler Class — spring-boot Architecture
Architecture documentation for the SpringBootExceptionHandler class in SpringBootExceptionHandler.java from the spring-boot codebase.
Entity Profile
Source Code
core/spring-boot/src/main/java/org/springframework/boot/SpringBootExceptionHandler.java lines 35–140
class SpringBootExceptionHandler implements UncaughtExceptionHandler {
private static final Set<String> LOG_CONFIGURATION_MESSAGES;
static {
Set<String> messages = new HashSet<>();
messages.add("Logback configuration error detected");
LOG_CONFIGURATION_MESSAGES = Collections.unmodifiableSet(messages);
}
private static final LoggedExceptionHandlerThreadLocal handler = new LoggedExceptionHandlerThreadLocal();
private final @Nullable UncaughtExceptionHandler parent;
private final List<Throwable> loggedExceptions = new ArrayList<>();
private int exitCode;
SpringBootExceptionHandler(@Nullable UncaughtExceptionHandler parent) {
this.parent = parent;
}
void registerLoggedException(Throwable exception) {
this.loggedExceptions.add(exception);
}
void registerExitCode(int exitCode) {
this.exitCode = exitCode;
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
try {
if (isPassedToParent(ex) && this.parent != null) {
this.parent.uncaughtException(thread, ex);
}
}
finally {
this.loggedExceptions.clear();
if (this.exitCode != 0) {
System.exit(this.exitCode);
}
}
}
private boolean isPassedToParent(Throwable ex) {
return isLogConfigurationMessage(ex) || !isRegistered(ex);
}
/**
* Check if the exception is a log configuration message, i.e. the log call might not
* have actually output anything.
* @param ex the source exception
* @return {@code true} if the exception contains a log configuration message
*/
private boolean isLogConfigurationMessage(@Nullable Throwable ex) {
if (ex == null) {
return false;
}
if (ex instanceof InvocationTargetException) {
return isLogConfigurationMessage(ex.getCause());
}
String message = ex.getMessage();
if (message != null) {
for (String candidate : LOG_CONFIGURATION_MESSAGES) {
if (message.contains(candidate)) {
return true;
}
}
}
return false;
}
private boolean isRegistered(@Nullable Throwable ex) {
if (ex == null) {
return false;
}
if (this.loggedExceptions.contains(ex)) {
return true;
}
if (ex instanceof InvocationTargetException) {
return isRegistered(ex.getCause());
}
return false;
}
static SpringBootExceptionHandler forCurrentThread() {
return handler.get();
}
/**
* Thread local used to attach and track handlers.
*/
private static final class LoggedExceptionHandlerThreadLocal extends ThreadLocal<SpringBootExceptionHandler> {
@Override
protected SpringBootExceptionHandler initialValue() {
SpringBootExceptionHandler handler = new SpringBootExceptionHandler(
Thread.currentThread().getUncaughtExceptionHandler());
Thread.currentThread().setUncaughtExceptionHandler(handler);
return handler;
}
}
}
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free