16

我有一个使用这个外部调用的假客户:

@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。肯定还有别的办法吗?

4

3 回答 3

4

您应该能够通过获取原因来获得从回退中抛出的异常HystrixRuntimeException

因此,要处理您的自定义异常,您可以这样做:

try {
    getResourceA();
} catch (HystrixRuntimeException e) {
    if (e.getCause() instanceof MyException) {
        handleException((MyException)e.getCause());
    }
}
于 2016-08-17T11:01:24.703 回答
0

您可以使用 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()

于 2019-10-16T13:31:05.157 回答
0

如果你想替换 hystrix 抛出的超时异常,你可以这样写:

try {
    testClient.timeoutTest();
} catch (HystrixRuntimeException e) {
    Throwable fallbackException = e.getFallbackException();
    if (fallbackException.getCause().getCause() instanceof CustomException) {
        log.info("customer exception!");
    }
}
于 2021-01-14T05:53:42.647 回答