Прослушивание исключений в Spring Boot без контекста контроллера - PullRequest
0 голосов
/ 03 июля 2019

Иногда я получаю печально известную CJCommunicationsException после получения пары сообщений RabbitMQ с момента запуска моего проекта.Поскольку я практически не контролирую сервер MySQL, мне нужно выйти / перезапустить мое приложение Spring Boot, чтобы избавиться от исключения.

Поскольку контекст не включает @Controller или @RestController (Я использую слушатель RabbitMQ), я не могу поймать исключение с @ControllerAdvice и @ExceptionHandler.Я пытаюсь сделать что-то вроде:

public static void main(String... args) throws Exception {
    while(true){
        try(ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args)) {
            CompletableFuture<Throwable> throwableFuture = new CompletableFuture<>();
            Thread.setDefaultUncaughtExceptionHandler(
                    (thread, throwable) -> throwableFuture.completeExceptionally(throwable));
            throwableFuture.get();
        } catch (Exception | VirtualMachineError t) {
            //log error
        }
    }
}

, как указано здесь , но поскольку исключение перехватывается встроенным Tomcat в org.apache.catalina.core.StandardWrapperValve.invoke, это не помогает, так как этот ответ указывает.

Как мне преодолеть это?

1 Ответ

0 голосов
/ 04 июля 2019

Похоже, вам следует создать пользовательский бин типа org.springframework.util.ErrorHandler со стратегией исключения (в случае org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler это org.springframework.amqp.rabbit.listener.FatalExceptionStrategy) и передать его фабрике контейнеров.

Это действительно сложночтобы предоставить вам рабочую конфигурацию без вашей текущей конфигурации, но ваша установка может выглядеть примерно так:

@Configuration
@EnableRabbit
public class RabbitMqConfiguration {

// ... other @Bean-s

@Bean
public SimpleRabbitListenerContainerFactory exportPartyListenerContainer() {
     SimpleRabbitListenerContainerFactory listenerContainer = new SimpleRabbitListenerContainerFactory();
     //... custom setup
     listenerContainer.setErrorHandler(errorHandler());
     return listenerContainer;
}

@Bean
public ErrorHandler errorHandler() {
   return new ConditionalRejectingErrorHandler(new YourCustomExceptionStrategy());
} 

} 

И реализация:

public class YourCustomExceptionStrategy extends DefaultExceptionStrategy {

    //.. some @Autowire-s if you need      

    @Override
    public boolean isFatal(Throwable t) {
         // ... your handling
    }
}

Может быть, стоит реализоватьобычай org.springframework.util.ErrorHandler и передать его фабрике контейнеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...