По сути, серия событий выглядела следующим образом:
- MyEvent опубликован
- listener1 вызывается
- listener2 вызывается, но обнаруживает исключение
Нет указаний на то, что произошло исключение (например, в console/logs) - listener3 НЕ вызывается
- MyEvent опубликован
- вызывается прослушиватель1
- вызывается прослушиватель2, но обнаруживается исключение
- вызывается прослушиватель3
< li>исключение регистрируется через мой errorHandler
Если приложение не перейдет к следующему прослушивателю после исключения в стандартном конфигурации, почему он делает это, когда я настраиваю его для печати исключения?
У меня такое ощущение, что исключение «невидимо» ( нет никаких признаков того, что произошло исключение) может быть связано с тем, что я использовал Исполнителей? Однако я не понимаю несоответствия в том, являются ли исключения «блокирующими» или нет.
Моя тестовая настройка:@Configuration
public class AppConfig {
// If the following configuration is present (just logging the NPE), all listeners are invoked.
// However, if it is removed, the NPE is not recorded, and only listeners 1 and 2 are invoked.
@Bean
public SimpleApplicationEventMulticaster applicationEventMulticaster() {
SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();
multicaster.setErrorHandler(throwable -> {
System.err.println("Exception in event listener: " + throwable.getMessage());
});
return multicaster;
}
}
@EnableScheduling
@Component
public class EventsTesting {
private final ApplicationEventPublisher publisher;
private final ExecutorService executor = Executors.newSingleThreadExecutor();
@Autowired
private EventsTesting(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
// PUBLISHING MyEvent EVERY 5 SECONDS
@Scheduled(fixedRate = 5000)
private void publishEvent() {
System.out.println("PUBLISH EVENT");
executor.submit(() -> publisher.publishEvent(new MyEvent(this)));
}
// EVENT LISTENERS HANDLE THE EVENT SEQUENTIALLY
@Order(1)
@EventListener
private void handleMyEvent1(MyEvent event) {
System.out.println("LISTENER 01");
}
@Order(2)
@EventListener
private void handleMyEvent2(MyEvent event) {
System.out.println("LISTENER 02");
String npe = event.getNull().toLowerCase();
}
@Order(3)
@EventListener
private void handleMyEvent3(MyEvent event) {
System.out.println("LISTENER 03");
}
public static class MyEvent extends ApplicationEvent {
public MyEvent(Object source) {
super(source);
}
public String getNull() { return null;}
}
}
При наличии конфигурации SimpleApplicationEventMulticaster я вижу следующие журналы:
PUBLISH EVENT
LISTENER 01
LISTENER 02
LISTENER 03
Exception in event listener: Cannot invoke "String.toLowerCase()" because the return value of "com.example.eventhandlingbug.EventsTesting$MyEvent.getNull()" is null
PUBLISH EVENT
LISTENER 01
LISTENER 02
LISTENER 03
Exception in event listener: Cannot invoke "String.toLowerCase()" because the return value of "com.example.eventhandlingbug.EventsTesting$MyEvent.getNull()" is null
Однако без конфигурации я вижу это:
PUBLISH EVENT
LISTENER 01
LISTENER 02
PUBLISH EVENT
LISTENER 01
LISTENER 02
Подробнее здесь: https://stackoverflow.com/questions/792 ... t-blocking