@Test
  void retryableExceptionInDecoder() throws Exception {
    server.enqueue(new MockResponse().setBody("retry!"));
    server.enqueue(new MockResponse().setBody("success!"));

    TestInterfaceAsync api =
        new TestInterfaceAsyncBuilder()
            .decoder(
                new StringDecoder() {
                  @Override
                  public Object decode(Response response, Type type) throws IOException {
                    String string = super.decode(response, type).toString();
                    if ("retry!".equals(string)) {
                      throw new RetryableException(
                          response.status(),
                          string,
                          HttpMethod.POST,
                          NON_RETRYABLE,
                          response.request());
                    }
                    return string;
                  }
                })
            .target("http://localhost:" + server.getPort());

    assertThat(api.post().get()).isEqualTo("success!");
    assertThat(server.getRequestCount()).isEqualTo(2);
  }
when you must parse a 2xx status to determine if the operation succeeded or not.
core/src/test/java/feign/AsyncFeignTest.java