HOTFIX Error handling for jdbc connection error, pool out of connections
This commit is contained in:
parent
7eb8ca2013
commit
063576243a
@ -0,0 +1,39 @@
|
||||
package com.iqser.red.service.peristence.v1.server.errorhandling;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CannotGetJdbcConnectionExceptionHandler extends ISpringContextUncaughtExceptionService<CannotGetJdbcConnectionException> {
|
||||
|
||||
public CannotGetJdbcConnectionExceptionHandler(ConfigurableApplicationContext context) {
|
||||
|
||||
super(context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<CannotGetJdbcConnectionException> getExceptionClass() {
|
||||
|
||||
return CannotGetJdbcConnectionException.class;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleException(CannotGetJdbcConnectionException e) {
|
||||
|
||||
log.error("Cannot get JDBC connection. Please check the database connection. Will terminate application now!: {}", e.getMessage(), e);
|
||||
try {
|
||||
SpringApplication.exit(context, () -> 0);
|
||||
} catch (Exception ex) {
|
||||
log.error("Error while trying to exit the application. Calling System.exit", ex);
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.iqser.red.service.peristence.v1.server.errorhandling;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public abstract class ISpringContextUncaughtExceptionService<T extends Throwable> {
|
||||
|
||||
protected final ApplicationContext context;
|
||||
|
||||
|
||||
protected ISpringContextUncaughtExceptionService(ApplicationContext context) {this.context = context;}
|
||||
|
||||
|
||||
public final void handleUncaughtException(Thread t, Throwable e) {
|
||||
|
||||
log.warn("Uncaught exception in thread: {}", t.getName(), e);
|
||||
checkException(e);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public abstract Class<T> getExceptionClass();
|
||||
|
||||
|
||||
public abstract void handleException(T e);
|
||||
|
||||
|
||||
private void checkException(Throwable e) {
|
||||
|
||||
if (e == null) {
|
||||
return;
|
||||
}
|
||||
var cause = e;
|
||||
do {
|
||||
if (cause.getClass().equals(getExceptionClass())) {
|
||||
log.error("Handling exception: {}", cause.getMessage(), cause);
|
||||
handleException((T) cause);
|
||||
}
|
||||
cause = cause.getCause();
|
||||
} while (cause != null);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.iqser.red.service.peristence.v1.server.errorhandling;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SpringContextUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
|
||||
private final List<ISpringContextUncaughtExceptionService> iSpringContextUncaughtExceptionServices;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
|
||||
Thread.setDefaultUncaughtExceptionHandler(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
|
||||
iSpringContextUncaughtExceptionServices.forEach(service -> service.handleUncaughtException(t, e));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
package com.iqser.red.service.peristence.v1.server.integration.errorhandling;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.iqser.red.service.peristence.v1.server.errorhandling.CannotGetJdbcConnectionExceptionHandler;
|
||||
import com.iqser.red.service.peristence.v1.server.errorhandling.SpringContextUncaughtExceptionHandler;
|
||||
import com.iqser.red.storage.commons.StorageAutoConfiguration;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SpringContextUncaughtExceptionHandlerTest.SimpleApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class SpringContextUncaughtExceptionHandlerTest {
|
||||
|
||||
@Autowired
|
||||
public CannotGetJdbcConnectionExceptionHandlerTest cannotGetJdbcConnectionExceptionHandler;
|
||||
|
||||
@Autowired
|
||||
public SpringContextUncaughtExceptionHandler springContextUncaughtExceptionHandler;
|
||||
|
||||
public static class CannotGetJdbcConnectionExceptionHandlerTest extends CannotGetJdbcConnectionExceptionHandler {
|
||||
|
||||
private boolean hasException;
|
||||
|
||||
|
||||
public CannotGetJdbcConnectionExceptionHandlerTest(ConfigurableApplicationContext context) {
|
||||
|
||||
super(context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleException(CannotGetJdbcConnectionException e) {
|
||||
|
||||
this.hasException = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testExceptionHandling() {
|
||||
|
||||
assertThat(cannotGetJdbcConnectionExceptionHandler.hasException).isFalse();
|
||||
new Thread(() -> {
|
||||
throw new RuntimeException("base exception", new CannotGetJdbcConnectionException("Test"));
|
||||
}).start();
|
||||
Thread.sleep(500);
|
||||
assertThat(cannotGetJdbcConnectionExceptionHandler.hasException).isTrue();
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
public static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public CannotGetJdbcConnectionExceptionHandlerTest cannotGetJdbcConnectionExceptionHandlerTest(ConfigurableApplicationContext context) {
|
||||
|
||||
return new CannotGetJdbcConnectionExceptionHandlerTest(context);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public SpringContextUncaughtExceptionHandler springContextUncaughtExceptionHandler(CannotGetJdbcConnectionExceptionHandlerTest handler) {
|
||||
|
||||
return new SpringContextUncaughtExceptionHandler(List.of(handler));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Import(TestConfiguration.class)
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, StorageAutoConfiguration.class})
|
||||
public static class SimpleApplication {
|
||||
|
||||
public static void main(String args[]) {
|
||||
|
||||
SpringApplication.run(SimpleApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user