【问题标题】:How to catch FeignClient exception如何捕获 FeignClient 异常
【发布时间】:2017-03-14 17:24:10
【问题描述】:

我尝试捕获从 FeignClient 连接的另一个微服务收到的异常。我已经制作了自定义 ErrorDecoder,并且

public class CustomErrorDecoder implements ErrorDecoder {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final ErrorDecoder defaultErrorDecoder = new Default();

    @Override
    public Exception decode(String methodKey, Response response) {

        if (response.status() >= 400 && response.status() <= 499) {
            log.info("----------------- "+methodKey+" , "+response.status()+" , "+ response.reason());
            return new RestApiException(99,99,"");
        }
        return defaultErrorDecoder.decode(methodKey, response);
    }
} 

RestApiException 扩展异常的地方。

@ControllerAdvice
public class GlobalControllerAdvice {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(RestApiException.class)
    public ResponseEntity<RestApiException> handleException(RestApiException exception, HttpServletRequest req) {
        log.error("Sending error to client ( "+req.getUserPrincipal().getName()+" ) \"{}\"", exception.getErrMsg());
        return new ResponseEntity<RestApiException>(exception, exception.getStatus());
    }

    @ExceptionHandler(Throwable.class)
    public ResponseEntity<RestApiException> handleException(Throwable throwable, HttpServletRequest req) {
        RestApiException exception=new RestApiException(HttpStatus.INTERNAL_SERVER_ERROR, 100, 100,
                throwable.getMessage());
        return handleException(exception, req);
    }

结果,当我得到

HttpStatus.INTERNAL_SERVER_ERROR, 100, 100, throwable.getMessage());

但不是expexted自定义异常,我尝试在CustomErrorDecoder中设置。

我做错了什么,为什么我不能调用 RetAppiException 并将错误答案返回给休息客户端。

谢谢。

【问题讨论】:

  • 因为您一遍又一遍地调用相同的方法...您一遍又一遍地调用handleException(throwable) 方法。另一种方法具有不同的签名handleException(exception, request),但您没有调用它。
  • 我认为主要原因是 (RestApiException.java:25) ~[classes/:na].,如果我阻止这个调用代码 (@ExceptionHandler(Throwable.class)),我会得到相同的结果没有 ciclong 调用的错误。
  • 不,这不是......您的问题实际上是您一遍又一遍地调用相同的方法。
  • 我添加了有问题的额外信息。
  • 我放弃了。显然,您一遍又一遍地调用相同的方法,无论您提供多少信息,这种情况仍在发生。

标签: spring-mvc netflix-feign


【解决方案1】:

您无法使用@ControllerAdvice 捕获 FeignClient 的异常。异常处理程序不会捕捉到 feign 客户端、错误解码器产生的异常..

一个简单的解决方案是捕获您的 feign 调用,然后抛出您想要的异常。

try{
   feignClient.method();
} catch(Exception ex){
  //throw exceptions you want
  throw new YourException();
}

然后你就可以处理它了:

@ControllerAdvice
public class GlobalControllerAdvice {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(YourException.class)
    public ResponseEntity<RestApiException> handleException(RestApiException exception, HttpServletRequest req) {
        //impl
    }

}

【讨论】:

  • 很遗憾没有。 Feign Client 异常被 HystrixRuntimeException 覆盖,所以我丢失了第一个异常原因,我可以捕获并识别到 CustomErrorDecoder。所以,@ControllerAdvice 非常好地捕获所有异常,但只有 HystrixRuntimeException。你的决定也捕获了 HystrixRuntimeException。
  • 我不知道你用的是Hystrix,那就更简单了。
  • 这并不完全正确,因为您可以捕捉到FeignException,如stackoverflow.com/a/56241143/4567511 中所见
【解决方案2】:

您可以通过捕获 HystrixRuntimeException 并将 getCause() 强制转换为 FeignClientException 来捕获 feign 客户端异常。

例子:

@ExceptionHandler
public ResponseEntity<Problem> handleFeignException(HystrixRuntimeException ex, NativeWebRequest request) {
    final FeignException.FeignClientException feignClientException = (FeignException.FeignClientException) ex.getCause();
    return handleException(feignClientException, request);
}

【讨论】:

    猜你喜欢
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多