Tratamiento de Errores en RestTemplate

Gestión de Errores en RestTemplate

Gestión de Errores en RestTemplate


Cuando trabajamos con RestTemplate en nuestras aplicaciones Spring Boot, uno de los factores que tenemos que tener en cuenta es realizar un tratamiento de Errores en RestTemplate, ya que nos va simplificar y dejar más claro nuestro código.

Código de estado capturados por RestTemplate

Por defecto RestTemplate nos va a capturar 3 tipos de status code cuando se produce algún error en una comunicación HTTP:

Los errores que va a capturar por defecto son:

  • Error de Cliente – HttpClientErrorException (4XX)
  • Error de Servidor – HttpServerErrorException (5XX)
  • Error desconocido – Status code desconocido.

Una de las aproximaciones que más se suele usar para capturar cualquier error en un RestTemplate suele ser hacer uso de un try – catch. Esta es una solución que funciona pero no es la más limpia, sería más eficaz hacer una solución común para todas las llamadas y así simplificar el código eliminando los bloques de try catch.

Crear ResponseErrorHandler para RestTemplate

La mejor opción para gestionar los errores que obtenemos de nuestras peticiones por RestTemplate es hacer a través de un error handler que gestione todas las peticiones de ese servicio.

Lo primero es crear nuestra excepción custom:

public class RestTemplateCustomError extends RuntimeException {

  private HttpStatus statusCode;
  private String error;

  public RestTemplateCustomError(HttpStatus statusCode, String error) {
    super(error);
    this.statusCode = statusCode;
    this.error = error;
  }
  
  // TODO getters ... 
  // TODO toString ...
}

Para poder gestionar los errores de nuestro RestTemplate vamos a crear una clase que implemente a ResponseErrorHandler y que devuelva el error creado antes:

@Component
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() == HttpStatus.BAD_REQUEST) {
        throw new RestTemplateCustomError(response.getStatusCode(), "Bad Request");

    }

    if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) {
        throw new RestTemplateCustomError(response.getStatusCode(), "Not Found");
    }

    throw new RestTemplateCustomError(response.getStatusCode(), "Unknown status code");
  }
}

Lo que hemos hecho en la clase anterior ha sido crear una clase para detectar los errores que se producen en nuestro RestTemplate y esta clase será la encargada de gestionarla. Pero el mensaje de error que devolvemos es poco intuitivo y claro así que vamos a mejorarlo.

Para mejorar el código anterior vamos a sacar el mensaje de error de la siguiente manera:

try (BufferedReader reader = new BufferedReader(
				new InputStreamReader(httpResponse.getBody()))) {
			String httpBodyResponse = reader.lines().collect(Collectors.joining(""));

			errorMessage = httpBodyResponse;
                        throw new RestTemplateCustomError(response.getStatusCode(), errorMessage);


		}

Con el fragmento anterior recorremos la respuesta y obtenemos el mensaje de error, con lo que nuestro método handleError quedaría de la siguiente manera:

	public void handleError(ClientHttpResponse response) throws IOException {

		if (response.getStatusCode().is4xxClientError() || (response.getStatusCode().is5xxServerError())) {
                      try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.getBody()))) {
			String httpBodyResponse = reader.lines().collect(Collectors.joining(""));

			String errorMessage = httpBodyResponse;
                        throw new RestTemplateCustomError(response.getStatusCode(), errorMessage);

		}
	
	    }
        }

Una vez hemos creado nuestro error handler lo tenemos que inyectar al RestTemplate:

@Autowired
public Rest(RestTemplateBuilder restTemplateBuilder) {
        RestTemplate restTemplate = restTemplateBuilder
          .errorHandler(new RestTemplateResponseErrorHandler())
          .build();
    }

Otros artículos que te pueden interesar

Gestión Rest de errores con Spring Boot

Excepciones personalizadas

Conclusión

En esta entrada hemos visto una parte de la comunicación rest que es el tratamiento de Errores en RestTemplate. Una buena gestión de los errores nos va a permitir una correcta identificación y tratamiento de cualquier error que se produzca durante nuestras comunicaciones.

Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *