Spring cloud Hystrix回退引发的捕获异常?

Spring cloud Hystrix回退引发的捕获异常?,spring-cloud,hystrix,spring-cloud-netflix,Spring Cloud,Hystrix,Spring Cloud Netflix,我正在设计一个服务facade,我有一个方法签名,如下所示: public Policy getPolicy(长policyId)抛出PolicyNotFoundException 如果没有什么不好的事情发生,那么将返回一个策略对象(简单POJO)。如果未找到请求的策略,则会抛出一个选中的异常PolicyNotFoundException(只是作为参考-当涉及到应用程序内异常处理的最佳实践时,我们会遵循) 服务外观层之上的层(在本例中为a)知道如何处理此类PolicyNotFoundExcep

我正在设计一个服务facade,我有一个方法签名,如下所示:

public Policy getPolicy(长policyId)抛出PolicyNotFoundException
如果没有什么不好的事情发生,那么将返回一个策略对象(简单POJO)。如果未找到请求的策略,则会抛出一个选中的异常PolicyNotFoundException(只是作为参考-当涉及到应用程序内异常处理的最佳实践时,我们会遵循)

服务外观层之上的层(在本例中为a)知道如何处理此类PolicyNotFoundException并返回适当的负载

我正试图通过以下方式将其合并到HystrixCommand中:

@HystrixCommand(groupKey=“PolicyService”,fallbackMethod=“getPolicySafe”,ignoreExceptions={PolicyNotFoundException.class})
公共策略getPolicy(长policyId)引发PolicyNotFoundException{
info(“获取策略{}”,policyId);
//为测试目的模拟一些错误条件
抛出新的RuntimeException(“发生了什么事!”);
}
私有策略getPolicySafe(长policyId,Throwable t)抛出PolicyNotFoundException{
LOGGER.warn(“返回断路器获取策略{}”,policyId,t);
抛出新的PolicyNotFoundException(policyId);
}
基本上,我希望我的断路器的行为就像原始查找没有找到策略一样。不过,我遇到的问题是,我从回退方法中抛出的异常在翻译过程中丢失了。我在上面的层中看到的异常是命令方法引发的RuntimeException,而不是回退方法引发的异常。有办法解决这个问题吗?我也不想更改原始方法的约定,也不想让它上面的层知道任何事情,除非在找不到策略的情况下必须捕获PolicyNotFoundException。这里需要的任何东西都应该在这个服务外观层中捕获


我们将非常感谢您的任何帮助。谢谢

这是hystrix的默认行为。“若命令有回退,则只有触发回退逻辑的第一个异常才会传播到调用方”


请参阅错误传播部分。

这是hystrix的默认行为。“若命令有回退,则只有触发回退逻辑的第一个异常才会传播到调用方”


请参阅错误传播部分。

因此,根据@Spencergib给出的链接,我可能在升级到Hystrix 1.5.7后找到了解决方案。此代码按预期工作

PolicyRestController.java

@RestController
@请求映射(“/policies”)
公共类警察{
私有静态最终记录器Logger=LoggerFactory.getLogger(PoliciesApi.class);
@自动连线
私人保单服务;
@RequestMapping(value=“/{policyId}”,method=RequestMethod.GET,products={MediaTypes.POLICY\u JSON\u value,MediaTypes.POLICY\u XML\u value})
公共策略getPolicy(@PathVariable long policyId){
试一试{
//这只是为了简单起见。这个方法还有更多内容(输入验证等)
返回此.policyService.getPolicy(policyId);
}
捕获(PolicyNotFoundException ex){
//NotFoundException是一个用@ResponseStatus(HttpStatus.NOT_FOUND)注释的运行时异常
//因此,服务将404返回给客户端
info(“未找到策略{}”,例如getPolicyId(),例如);
抛出new NotFoundException(String.format(“未找到策略%s”,例如getPolicyId());
}
}
}
PolicyService.java

公共接口策略服务{
@可缓存(“所有策略”)
公共列表getPolicies();
@可缓存(“策略”)
公共策略getPolicy(长policyId)抛出PolicyNotFoundException;
}
PolicyServiceImpl.java:

@服务
公共类PolicyServiceImpl实现PolicyService{
@HystrixCommand(groupKey=“PolicyService”,fallbackMethod=“getPolicySafe”,ignoreExceptions={PolicyNotFoundException.class})
公共策略getPolicy(长policyId)引发PolicyNotFoundException{
info(“获取策略{}”,policyId);
//为测试目的模拟一些错误条件
抛出新的RuntimeException(“发生了什么事!”);
}
@HystrixCommand(groupKey=“PolicyService”,ignoreExceptions={PolicyNotFoundException.class},raiseHystrixExceptions={HystrixException.RUNTIME_EXCEPTION})
私有策略getPolicySafe(长policyId)引发PolicyNotFoundException{
//这里是我们的回退,我们想要记录一个警告&简单地通过抛出与API相同的意外异常,就好像没有找到策略一样
LOGGER.warn(“返回断路器以获取策略{}”,policyId);
抛出新的PolicyNotFoundException(policyId);
}
}

基于@Spencergib给出的链接,我可能在升级到Hystrix 1.5.7后找到了解决方案。此代码按预期工作

PolicyRestController.java

@RestController
@请求映射(“/policies”)
公共类警察{
私有静态最终记录器Logger=LoggerFactory.getLogger(PoliciesApi.class);
@自动连线
私人保单服务;
@RequestMapping(value=“/{policyId}”,method=RequestMethod.GET,products={MediaTypes.POLICY\u JSON\u value,MediaTypes.POLICY\u XML\u value})
公共策略getPolicy(@PathVariable long policyId){
试一试{
//这只是为了简单起见。这个方法还有更多内容(输入验证等)
返回此.policyService.getPolicy(policyId);
}
捕获(PolicyNotFoundException ex){
//NotFoundException是一个用@ResponseStatus(HttpStatus.NOT_FOUND)注释的运行时异常
//因此,服务将404返回给客户端
info(“未找到策略{}”,例如getPolicyId(),例如);
抛出new NotFoundException(String.format)(“未找到策略%s”
@Service
public class PolicyServiceImpl implements PolicyService {
  @HystrixCommand(groupKey = "PolicyService", fallbackMethod = "getPolicySafe")
  public Policy getPolicy(long policyId) throws PolicyNotFoundException {
    LOGGER.info("Getting policy {}", policyId);
    throw new PolicyNotFoundException(); // throw real PolicyNotFoundException if policy is absent for the given id
  }

  @HystrixCommand(groupKey = "PolicyService")
  private Policy getPolicySafe(long policyId) throws PolicyNotFoundException {
    // Here is we hit our fallback we want to log a warning & simply act as if the policy wasn't found by throwing the same contingency exception as the API does
    LOGGER.warn("Falling back to circuit-breaker for getting policy {}", policyId);

    throw new PolicyNotFoundException(policyId);
  }
}
@Component
public class HystrixClient {

  @HystrixCommand(ignoreExceptions = {ClientArgumentException.class})
  public POJO getPojo(String id)
        throws ClientNoDataFoundException, ClientArgumentException, ClientGeneralException {

    //call my service and return POJO
  }
}

@Component
public TrueClientUsedForAnotherSerivce {

  @Autowired
  HystrixClient hystrixClient;

 public POJO getPojo(String id)
        throws ClientNoDataFoundException, ClientArgumentException, ClientGeneralException, ClientOpenCircuitException {
    try {           
        POJO result = hystrixClient.getCellular(id);            

        return result;
    }
    catch(HystrixRuntimeException e) {
        LOG.debug("The circuit is open");
        throw new ClientOpenCircuitException("Open circuit");
    }
}