Соглашение Java состоит в том, что методы слушателя не генерируют исключения. Очевидно, что ошибки программирования могут заставить слушателя вызвать исключение RuntimeException, но источник событий не сможет восстановить его, поскольку он оставит объекты программы в каком-то неизвестном, возможно, несовместимом состоянии.
Поэтому слушатель должен перехватить проверенные исключения и либо восстановить их (например, выполнить откат транзакции), либо сообщить о них другому объекту. Я часто использую интерфейс ErrorHandler, который выглядит примерно так:
public interface ErrorHandler {
public void errorOccurred(String whatIWasTryingToDo, Exception failure);
}
Слушатель событий сообщает свой ErrorHandler об ошибках, которые произошли.
public class SomeClass implements SomeKindOfListener
private final ErrorHandler errorHandler;
... other fields ...
public SomeClass(ErrorHandler errorHandler, ... other parameters ... ) {
this.errorHandler = errorHandler;
...
}
public void listenerCallback(SomeEvent e) {
try {
... do something that might fail ...
}
catch (SomeKindOfException e) {
errorHandler.errorOccurred("trying to wiggle the widget", e);
}
}
}
Я инициализирую прослушиватели событий реализацией этого, которая обрабатывает сбой любым способом, который имеет смысл в тот момент в приложении. Это может вызвать всплывающее диалоговое окно, показать мигающий значок ошибки в строке состояния, зарегистрировать сообщение аудита или прервать процесс, например.