2016-11-01 23 views
1

FeignClientによって接続された別のマイクロサービスから受け取った例外をキャッチしようとします。カスタムErrorDecoderを作成しました。FeignClient例外をキャッチする方法

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); 
    } 

、私は< --- HTTP/1.1 400不正な要求(5380ms)を取得 私が持っているデフォルトのエラーメッセージ

HttpStatus.INTERNAL_SERVER_ERROR、100、100、 スロー可能。 getMessage());

私はCustomErrorDecoderで設定しようとする、expexedカスタム例外ではありません。

なぜ私は間違っているのですか?RetAppiExceptionを呼び出して、エラー応答をクライアントに返すことができないのはなぜですか?

ありがとうございました。

+0

あなたは何度も同じメソッドを呼び出しているので...あなたは何度も 'メソッド' handleException(スロー可能オブジェクト)を呼び出しています。他のメソッドは、異なる署名 'handleException(exception、request)'を持っていますが、呼び出すことはありません。 –

+0

主な理由は(RestApiException.java:25)〜[classes /:na]です。この呼び出しコード(@ExceptionHandler(Throwable.class))をブロックすると、ciclong呼び出しをしないと同じエラーが発生します。 – koa73

+0

いいえ、そうではありません...あなたの問題は、あなたが何度も同じメソッドを呼び出しているということです。 –

答えて

2

@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 
    } 

} 
+0

残念ながら、 Feignクライアントの例外がHystrixRuntimeExceptionによって上書きされたので、私はCustomErrorDecoderにキャッチして認識できる最初の例外理由を失いました。ですから、@ControllerAdviceはすべての例外を非常にうまくキャッチしますが、HystrixRuntimeExceptionのみです。あなたの決定はHystrixRuntimeExceptionもキャッチします。 – koa73

+0

私はあなたが 'ヒステリックス'を使っているのを知らなかった。 – Pau