【问题标题】:feign error handling by using feign decoder使用 feign 解码器进行 feign 错误处理
【发布时间】:2020-05-13 12:26:40
【问题描述】:

创建了服务'A',需要由服务'B'使用feign客户端调用 如果服务“A”由于某些验证而失败,则服务“A”发回包含以下详细信息的错误响应, (1)http状态码 (2)错误信息 (3) 自定义错误映射,其中包含自定义错误代码及其错误消息 例如,

在 Service 'B' 中,我们使用 feigndecoder 来处理 feign 异常,但它只提供 http 状态码而不是自定义错误码

而且,就我而言,对于不同的场景,http 状态代码是相同的,但自定义错误映射值是不同的。 结合两者(http状态码+自定义错误图),我们必须处理服务'B'中的异常。

请对此提出一些建议

【问题讨论】:

  • 能否在您的问题中添加源代码或更多信息?
  • 我们使用 FeignErrorDecoder 实现了 feign 的 ErrorDecode 并且我们覆盖了 decode 方法(public Exception decode(String methodKey, Response response)) 从响应中我们只能得到 http 状态而不是自定义错误映射, 上面提到了
  • 我们得到了解决方案和下面的解决方案,(1)您不需要错误解码器来处理假装异常。 (2)您只需要一个接受 FeignException 的异常处理程序 (3)从该 FeignException 中,我们可以调用 contentUtf8 方法来获取服务“A”发送的整个自定义异常响应。
  • 添加了在 github 上创建的示例 POC 我们有两个服务一个是员工服务,另一个是 feign 服务从 feignService 我们调用员工服务,如果员工服务由于某些错误/异常而失败并且相同错误响应可以通过 feignService 自定义。 PFB 存储库详细信息github.com/agarwalsudhanshu46/employeegithub.com/agarwalsudhanshu46/FeignService

标签: java spring spring-boot spring-cloud-feign feign


【解决方案1】:

您可以启用断路器,还可以根据返回的错误配置您的应用程序以应用不同的回退方法,请按照以下步骤操作:

1.- 启用断路器本身

@SpringBootApplication
@EnableFeignClients("com.perritotutorials.feign.client")
@EnableCircuitBreaker
public class FeignDemoClientApplication {

2.- 创建你的后备 bean

@Slf4j
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PetAdoptionClientFallbackBean implements PetAdoptionClient {
@Setter
    private Throwable cause;
@Override
    public void savePet(@RequestBody Map<String, ?> pet) {
        log.error("You are on fallback interface!!! - ERROR: {}", cause);
    }
}

对于后备实施,您必须牢记以下几点:

  • 必须标记为@Component,它们在整个应用程序中是唯一的。
  • 后备 bean 应该有一个 Prototype 范围,因为我们希望为每个异常创建一个新的。
  • 使用构造函数注入进行测试。

3.- 您的 ErrorDecoder,根据返回的 HTTP 错误实施后备策略:


public class MyErrorDecoder implements ErrorDecoder {
private final ErrorDecoder defaultErrorDecoder = new Default();
@Override
    public Exception decode(String methodKey, Response response) {
        if (response.status() >= 400 && response.status() <= 499) {
            return new MyCustomBadRequestException();
        }
if (response.status() >= 500) {
            return new RetryableException();
        }
        return defaultErrorDecoder.decode(methodKey, response);
    }
}

4.- 在您的配置类中,将 Retryer 和 ErrorDecoder 添加到 Spring 上下文中:


@Bean
public MyErrorDecoder myErrorDecoder() {
  return new MyErrorDecoder();
}

@Bean
public Retryer retryer() {
    return new Retryer.Default();
}

您还可以向重试器添加自定义:


class CustomRetryer implements Retryer {
private final int maxAttempts;
    private final long backoff;
    int attempt;
public CustomRetryer() {
        this(2000, 5); //5 times, each 2 seconds
    }
public CustomRetryer(long backoff, int maxAttempts) {
        this.backoff = backoff;
        this.maxAttempts = maxAttempts;
        this.attempt = 1;
    }
public void continueOrPropagate(RetryableException e) {
        if (attempt++ >= maxAttempts) {
            throw e; 
        }
try {
            Thread.sleep(backoff);
        } catch (InterruptedException ignored) {
            Thread.currentThread().interrupt();
        }
    }
@Override
    public Retryer clone() {
        return new CustomRetryer(backoff, maxAttempts);
    }
}

如果您想获得有关如何在应用程序中实现 Feign 的功能示例,请阅读 this 文章。

【讨论】:

    猜你喜欢
    • 2018-03-21
    • 2017-06-05
    • 2016-12-17
    • 2018-12-25
    • 2020-11-14
    • 2017-05-21
    • 2021-12-17
    • 2016-06-25
    • 2020-04-28
    相关资源
    最近更新 更多