Могу ли я набросить пользовательскую ошибку, если время ожидания, защищенное от использования гистерезис?

У меня есть сторонний клиент с этим внешним вызовом:

@RequestMapping(method = RequestMethod.GET, value = "GetResourceA", consumes = "application/json")
@Cacheable("ResourceA")
List<Stop> getResourceA() throws MyOwnException;

И в моем application.yml у меня есть этот параметр:

hystrix:
  command:
    default:
      execution.isolation.thread.timeoutInMilliseconds: 1000
      fallback.enabled: false

Теперь, если getResourceA истечет, то есть требуется больше одной секунды, я либо получаю это:

com.netflix.hystrix.exception.HystrixRuntimeException: getResourceA timed-out and no fallback available

Или, если я определяю резервную копию, из которой я бросаю свое собственное исключение, я получаю следующее:

com.netflix.hystrix.exception.HystrixRuntimeException: getResourceA timed-out and fallback failed.

Могу ли я отказаться от собственного исключения из резервной копии?

Что делать, если я хочу отказаться от своего собственного исключения, когда служба отключена? Я бы хотел, чтобы у меня не было резервной копии (потому что у меня нет разумного значения для возврата из резервной копии), но вместо этого бросаю свою собственную ошибку, которую я могу поймать, и позволить программе возобновиться. Может кто-нибудь помочь мне с этим?

Обновление после ответа от Бена:

Итак, я пробовал этот подход с улавливанием HysterixRuntimeException и проверял, что вызвало его, но закончил с этим уродливым кодом:

try {
    getResourceA();
} catch (HystrixRuntimeException e) {
    if (e.getFailureType().name().equals("TIMEOUT")) {
        throw new MyOwnException("Service timed out");
    }
    throw e;
}

Все это, чтобы иметь возможность выкидывать MyOwnException при тайм-ауте. Неужели должен быть другой способ?

Ответ 1

Вы должны иметь возможность получить исключение, которое вы выбрали из своего резерва, получив причину HystrixRuntimeException

Итак, для обработки вашего настраиваемого исключения вы можете сделать это:

try {
    getResourceA();
} catch (HystrixRuntimeException e) {
    if (e.getCause() instanceof MyException) {
        handleException((MyException)e.getCause());
    }
}

Ответ 2

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

public class ExceptionHandlerControllerAdvice extends ResponseEntityExceptionHandler
...

@ResponseStatus(BAD_REQUEST)
@ExceptionHandler(HystrixRuntimeException.class)
public ExceptionResponse handleHystrixRuntimeException(HystrixRuntimeException exception) {
    if(exception.getCause() instanceof MyException) {
        return handleMyException((MyException) exception.getCause());
...

А затем в моем классе конфигурации для моего FeignClient:

@Bean
public ErrorDecoder feignErrorDecoder() {
    return new ErrorDecoder() {
        @Override
        public Exception decode(String methodKey, Response response) {
            return new MyException("timeout");
        }
    };
}

Таким образом, вам не нужно несколько вложенных getCause()