Обработчики исключений

Необработанные исключения, выбрасываемые клиенту, передаются специальному механизму обработчиков.

Обработчик исключений – это бин Spring, реализующий интерфейс UiExceptionHandler. Его метод handle() должен обработать исключение и вернуть true или немедленно вернуть false, если данный обработчик не может обработать переданное исключение. Такое поведение создает "цепочку ответственности" для обработчиков.

Рекомендуется наследовать обработчики от базового класса AbstractUiExceptionHandler, который может разбирать цепочку исключений (включая упакованные внутри RemoteException) и обрабатывать определенные их типы. Поддерживаемые этим обработчиком типы исключений определяются путем передачи массива строк базовому конструктору из конструктора обработчика. Каждая строка массива должна содержать одно полное имя класса обрабатываемых исключений.

Предположим, у вас есть следующий класс исключений:

public class ZeroBalanceException extends RuntimeException {

    public ZeroBalanceException() {
        super("Insufficient funds in your account");
    }
}

Создайте обработчик для этого исключения со следующим конструктором:

@Component("uiex1_ZeroBalanceExceptionHandler")
public class ZeroBalanceExceptionHandler extends AbstractUiExceptionHandler {

    public ZeroBalanceExceptionHandler() {
        super(ZeroBalanceException.class.getName());
    }
}

Если класс исключения недоступен на стороне клиента, укажите его имя с помощью строкового литерала:

@Component("uiex1_ForeignKeyViolationExceptionHandler")
public class ForeignKeyViolationExceptionHandler extends AbstractUiExceptionHandler {

    public ForeignKeyViolationExceptionHandler() {
        super("java.sql.SQLIntegrityConstraintViolationException");
    }
    /*...*/
}

В случае использования AbstractUiExceptionHandler в качестве базового класса логика обработки находится в методе doHandle() и выглядит следующим образом:

@Component("uiex1_ZeroBalanceExceptionHandler")
public class ZeroBalanceExceptionHandler extends AbstractUiExceptionHandler {

    public ZeroBalanceExceptionHandler() {
        super(ZeroBalanceException.class.getName());
    }
    @Override
    protected void doHandle(String className, String message,
                            @Nullable Throwable throwable, UiContext context) {
        context.getNotifications().create(Notifications.NotificationType.ERROR)
                .withCaption("Error")
                .withDescription(message)
                .show();
    }
}

Если имени класса исключения недостаточно для принятия решения о том, может ли данный обработчик быть применен к данному исключению, определите метод canHandle(). Этот метод также принимает текст исключения. Если обработчик применим для исключения, метод возвращает true. Например:

@Component("uiex1_ZeroBalanceExceptionHandler")
public class ZeroBalanceExceptionHandler extends AbstractUiExceptionHandler {

    /*...*/

    @Override
    protected boolean canHandle(String className, String message,
                                @Nullable Throwable throwable) {
        return StringUtils.containsIgnoreCase(message,
                "Insufficient funds in your account");
    }
}

Интерфейс Dialogs, доступный через параметр UiContext метода doHandle(), предоставляет специальный диалог для отображения исключений, содержащий сворачиваемую область с полным стектрейсом исключения. Это диалоговое окно используется в обработчике по умолчанию, но вы можете использовать его и для собственных исключений, например:

@Override
protected void doHandle(String className, String message,
                        @Nullable Throwable throwable, UiContext context) {
    if (throwable != null) {
        context.getDialogs().createExceptionDialog()
                .withThrowable(throwable)
                .withCaption("Error")
                .withMessage(message)
                .show();
    } else {
        context.getNotifications().create(Notifications.NotificationType.ERROR)
                .withCaption("Error")
                .withDescription(message)
                .show();
    }
}