在没有定义错误解码器的情况下,Feign 客户端中的 throws 声明是否无用?

huangapple go评论79阅读模式
英文:

Is throws declaration in feign client useless without defined error decoder?

问题

我有一个类似这样的 Feign 客户端:

@FeignClient(name = "client")
public interface SomeClient {
    @RequestLine("GET /?q={q}")
    void execute(URI baseUrl, @Param("q") String q) throws SomeExceptionInMyCode;
}

针对这里的 throws SomeExceptionInMyCode,我在思考什么时候会抛出这个异常。没有为客户端定义配置,也没有错误解码器。异常的定义如下:

public class SomeExceptionInMyCode extends Exception{

    private final int statusCode;
    private final String reason;
    private final String body;
    
    // 获取器和设置器
}

在失败的情况下,是否会自动尝试将 HTTP 响应解码为这个异常?或者 throws SomeExceptionInMyCode 是多余的,可以移除而不会产生任何影响。

我在代码中进行了搜索,但从未发现过创建此异常的情况。

英文:

I have a feign client like this

@FeignClient(name = "client")
public interface SomeClient {
    @RequestLine("GET /?q={q}")
    void execute(URI baseUrl, @Param("q") String q) throws SomeExceptionInMyCode;
}

Looking to this throws SomeExceptionInMyCode I'm asking myself when this exception will be thrown. There is no configuration for client defined, no error decoder. Exception looks like this.

public class SomeExceptionInMyCode extends Exception{

    private final int statusCode;
    private final String reason;
    private final String body;
    
    // getters and setters
}

Will there be an automatic attempt to decode HTTP response to this exception in case of failure? Or throws SomeExceptionInMyCode is useless and can be removed without any impact.

I searched inside my code and this exception is never created.

答案1

得分: 2

是否会在请求失败时自动尝试解码 HTTP 响应以获取异常信息?

不会,它并不是这样工作的,SomeExceptionMyCode 不会被抛出。throws 子句是无效的。即使端点从其实现中抛出此异常,它也会被包装为 FeignException 的一个原因。

处理 Feign 客户端异常的正确方式是使用自定义异常处理 并实现 ErrorDecoder

public class StashErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {
        if (response.status() >= 400 && response.status() <= 499) {
            // 返回 4XX 异常
        }
        if (response.status() >= 500 && response.status() <= 599) {
            // 返回 5XX 异常
        }
    }
}

在这一点上,您可以执行自定义异常的创建和重新抛出操作。

另一种解决方案是使用类似于 Spring 的 @RestControllerAdvice

@RestControllerAdvice
public class ExceptionHandler {

    @ExceptionHandler(FeignException.class)
    public String handleFeignStatusException(FeignException e, HttpServletResponse response) {
        // ...
    }
}
英文:

> Will there be an automatic attempt to decode http response to this exception in case of failure?

Nope, it doesn't work like this and the SomeExceptionMyCode will not be thrown. The throws clause is useless. Even if the endpoint throws this exception from its implementation, it will be wrapped as a cause of FeignException.

The correct way to handle feign client exceptions is using Custom exception handling implementing ErrorDecoder:

public class StashErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {
        if (response.status() &gt;= 400 &amp;&amp; response.status() &lt;= 499) {
            // return 4XX exception
        }
        if (response.status() &gt;= 500 &amp;&amp; response.status() &lt;= 599) {
            // return 5XX exception
        }
    }
}

At this point you can perform the custom exception creation and rethrowing.

An alternative solution is to use Spring-alike @RestControllerAdvice:

@RestControllerAdvice
public class ExceptionHandler {

    @ExceptionHandler(FeignException.class)
    public String handleFeignStatusException(FeignException e, HttpServletResponse response) {
        // ...
    }

}

答案2

得分: 0

如果 StashErrorDecoder 抛出了已检查异常呢?这是允许的。在这种情况下,接口中的 throws 子句肯定会有所帮助。这样,您就可以捕获并处理 Feign 抛出的异常。至少应该可以这样工作。

英文:

What if the StashErrorDecoder throws a checked exception? That is allowed. In this case the throws clause in the interface surely helps. This way you can catch and handle the exception thrown by Feign. At least it should work this way.

huangapple
  • 本文由 发表于 2020年5月5日 15:56:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/61608343.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定