Root причина и распространение исключения в SAP Cloud SDK - PullRequest
1 голос
/ 27 мая 2020

Предположим, у меня есть поставщик, и при вызове метода get этого поставщика возникает какое-то исключение.

 Supplier<> supplier = () -> getSomething();
 ResilienceDecorator.executeSupplier( //Edit 1 - Could be ResilienceDecorator.executeCallable
                supplier,
                resilienceConfiguration,
                throwable -> {
                   log.error("Exception occured", throwable);
                   return null;
                });

Edit 1 - То же самое для ResilienceDecorator.executeCallable. Мне нужен согласованный API, чтобы знать, что пошло не так во время выполнения, т.е. что было проверено исключение ( Edit 1 - или Unchecked исключение ), вызвавшее сбой, чтобы я мог обрабатывать бизнес-логи c. Выбрасываемый объект не является root причиной исключения или чем-то еще, что было выброшено поставщиком.

Если мы не предоставляем бросаемую функцию, как указано выше, тогда каждое исключение оборачивается в ResilienceRuntimeException и нам нужна цепочка из getCause().getCause(), чтобы узнать, что пошло не так. Это внутреннее для SDK, которое может измениться. Снова необходим последовательный API.

Есть ли альтернативный и последовательный способ узнать, какое исключение выбрасывает поставщик? Мне может потребоваться всплыть или написать удобное сообщение на основе возникшего исключения, в зависимости от бизнес-логики c.

Редактировать 1 - Пример моей текущей ситуации.

Supplier<MatDocItm> supplier = () -> {
        ErpHttpDestination erpHttpDestination = DestinationAccessor.getDestination(S4_SYSTEM).asHttp().decorate(DefaultErpHttpDestination::new);
        return new CustomCommand(erpHttpDestination, params).execute();     
    }

    try {
        MatDocItm = ResilienceDecorator.executeSupplier(
                supplier,
                configuration
        );
    } catch (ResilienceRuntimeException e) {
        throw new ReadException("Failed to read from SAP S/4HANA", e);
    }

Поставщик может генерировать исключения времени выполнения, и на основе этих исключений я хочу дать удобное для пользователя сообщение об ошибке с надлежащим описанием.

Поставщик может выдать DestinationAccessException (что является исключением времени выполнения), если место назначения не может быть доступными, настроен неправильно или не соответствует определенным предварительным требованиям. Не только исключения, возникшие у поставщика, у меня есть TimeLimiterConfiguration, и если произойдет тайм-аут, тогда может быть выброшено TimeoutException.

Для приведенного выше примера MatDocItm ResilienceRuntimeException.getCause() даст com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextExecutionException. ResilienceRuntimeException.getCause().getCause() покажет исключение, которое фактически вызвало ошибку, т.е. DestinationAccessException. Теперь ThreadContextExecutionException является внутренним для sdk и может измениться при изменении реализации sdk. Останется ли эта деталь реализации замороженной и никогда не изменится в будущем, или есть какой-либо альтернативный способ получить причину root?

1 Ответ

2 голосов
/ 27 мая 2020

Я бы порекомендовал ExceptionUtils.throwableOfType для сопоставления типа исключения и подклассов. Альтернативно ExceptionUtils.throwableOfThrowable только для соответствия точному типу. Служебный класс, уже предоставленный зависимостью org.apache.commons:commons-lang3:3.10

Пример:

@Nullable
YourException cause = ExceptionUtils.throwableOfType(throwable, YourException.class);

Вы можете обработать результат, допускающий значение NULL, в операторе If.

Как поклонник свободно работающих API , Я бы предпочел go с java.util.Optional или io.vavr.control.Option.

...