0

I'm using RestTemplate to call my webservice's health actuator endpoint from another webservice of mine to see if the webservice is up. If the webservice is up, all works fine, but when it's down, I get an error 500, "Internal Server Error". If my webservice is down, I'm trying to catch that error to be able to handle it, but the problem I'm having is that I can't seem to be able to catch the error.

I've tried the following and it never enters either of my catch sections

@Service
public class DepositService {

  @Bean
  public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder
            .setConnectTimeout(Duration.ofMillis(3000))
            .setReadTimeout(Duration.ofMillis(3000))
            .build();
  }

  private static void getBankAccountConnectorHealth() {
    final String uri = "http://localhost:9996/health";

    RestTemplate restTemplate = new RestTemplate();

    String result = null;

    try {
      result = restTemplate.getForObject(uri, String.class);
    } catch (HttpClientErrorException exception) {
      System.out.println("callToRestService Error :" + exception.getResponseBodyAsString());
    } catch (HttpStatusCodeException exception) {
      System.out.println( "callToRestService Error :" + exception.getResponseBodyAsString());
    }

    System.out.println(result);
  }

}

I've also tried doing it this way, but same results. It never seems to enter my error handler class.

public class NotFoundException extends RuntimeException {
}

public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {

  @Override
  public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
    return (httpResponse.getStatusCode().series() == CLIENT_ERROR || httpResponse.getStatusCode().series() == SERVER_ERROR);
  }

  @Override
  public void handleError(ClientHttpResponse httpResponse) throws IOException {
    if (httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
      // handle SERVER_ERROR
      System.out.println("Server error!");
    } else if (httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
      // handle CLIENT_ERROR
      System.out.println("Client error!");

      if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) {
        throw new NotFoundException();
      }
    }
  }



}

@Service
public class DepositService {

  @Bean
  public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder
            .setConnectTimeout(Duration.ofMillis(3000))
            .setReadTimeout(Duration.ofMillis(3000))
            .build();
  }

  private static void getAccountHealth() {
    final String uri = "http://localhost:9996/health";

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setErrorHandler(new RestTemplateResponseErrorHandler());

    String result = null;

    result = restTemplate.getForObject(uri, String.class);

    System.out.println(result);
  }

}

Any suggestions as to how I can call my webservice's health actuator from another webservice and catch if that webservice is down?

Steve B
  • 557
  • 2
  • 7
  • 23

2 Answers2

0

It looks like the getForObject doesn't throw either of the exceptions you are catching. From the documentation, it throws RestClientException. The best method I have found for identifying thrown exceptions is to catch Exception in the debugger and inspect it to find out if it's useful.

With the second method, I'm not sure why you would create a bean method for the RestTemplate and then create one with new. You probably should inject your RestTemplate and initialise the ResponseErrorHandler with the RestTemplateBuilder::errorHandler method.

Hopey One
  • 1,681
  • 5
  • 10
  • You are correct, the problem I was having with my first method was that I was catching the wrong exception. After take a good look at console, it's throwing ResourceAccessException. As for my bean method, with that method I get this error "Field restTemplate in ca.service.DepositService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found." – Steve B Dec 11 '20 at 14:23
0

Internal serve error throw HttpServerErrorException You should catch this exception if you want to handle it However the better way to do that is using error handler you can see the following posts to see how to do that:

  1. spring-rest-template-error-handling

  2. spring-boot-resttemplate-error-handling

Tashkhisi
  • 2,070
  • 1
  • 7
  • 20