Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the Response Text in Spring REST exception handlers?

I'm working on a Spring REST controller, specifically on an exception handler. The exception handler works as intended and my JUnit-Test (using the Spring HTTP client) shows that the correct HTTP Status code (400) is received at the client. The HTTP client automatically translates this into a HttpClientErrorException.

However, printing the HttpClientErrorException always produces the following result for me:

HttpClientErrorException: 400 null

... and the null part is what worries me. Shouldn't this be the place where the message of the server-side exception is supposed to be?

I checked the source code of the HTTP client to see where the client-side exception is thrown. It looks like this:

throw new HttpClientErrorException(statusCode, response.getStatusText(), response.getHeaders(), getResponseBody(response), getCharset(response));

Debugging this call revealed that response.getStatusText() is null in my case.

My question is: How do you design your ResponseEntity on the server-side such that the HTTP client finds the server-side exception message in response.getStatusText() instead of null?

Mine currently looks like this:

@ExceptionHandler({ MyCustomException.class })
public ResponseEntity<String> handleException(final HttpServletRequest req, final MyCustomException e) {
    HttpHeaders headers = new HttpHeaders();
    headers.set("Content-type", "text/plain");
    String body = e.toString();
    return new ResponseEntity<>(body, headers, HttpStatus.BAD_REQUEST);
}

... and I get null in the client side status text.

like image 449
Alan47 Avatar asked Sep 19 '17 15:09

Alan47


People also ask

How do I send a custom error message in REST API spring boot?

The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field. Although we can only return a generic error message, we can specify exception-specific error messages.

How do I change the response status in spring boot?

If we want to specify the response status of a controller method, we need to annotate that method with the @ResponseStatus annotation. It has two interchangeable arguments for the desired response type: code and value. Note, that when we set reason, Spring calls HttpServletResponse. sendError().

How do you handle an exception in spring boot using annotations?

The @ExceptionHandler is an annotation used to handle the specific exceptions and sending the custom responses to the client. Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown.


1 Answers

I must admit that I got fooled on this one. The null value printed by the Spring HttpClientErrorException is the statusText. This text is static. For example, for Status Code 404, the defined status text is "not found". There is no way to change it.

In order to receive the actual exception code, then the method suggested by Utku is exactly right. The small gotcha is that the error message needs to be extracted from HttpClientErrorException#getResponseBodyAsString(), not from HttpClientErrorException#getStatusText() like I tried.

like image 70
Alan47 Avatar answered Oct 23 '22 09:10

Alan47