Search code examples
javaspringspring-bootspring-mvcresttemplate

Get stack trace of Exception through spring rest template


I have 2 services - Service 1 and Service 2. Service 1 calls some Service 2 API through Spring Rest Template. Now Some exception happened in Service 2. I need the whole stack trace of it in Service 1. How to get it ?

Service 1  ---calls--> Service 2

Does the stack trace even get passed to Service 1 by Spring ?

You can say I am calling like this :

HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
return restTemplate.exchange("http://localhost:8080/products", HttpMethod.GET, entity, String.class).getBody();

Solution

  • I need the whole stack trace of it in Service 1. How to get it ?

    So there are ways to get it , in essence you have to implement. You can get your relevant exception message/trace in JSON response from Service 2 . That is , when there is any exception at Service 2 end then , we can configure response to send relevant exception information.

    In this post there are 3 answers explaining different ways to achieve, also this one. Now on :

    Does the stack trace even get passed to Service 1 by Spring ?

    Normally any unhandled/runtime exception thrown when processing a web-request causes the server to return an HTTP 500 response.

    So the answer is spring does not transfer the stack trace to Service 1 rather respond with error HTTP 500 and the most likely message of your exception.

    However, any exception that you write yourself can be annotated with the @ResponseStatus annotation (which supports all the HTTP status codes defined by the HTTP specification).

    When an annotated exception is thrown from a controller method, and not handled elsewhere, it will automatically cause the appropriate HTTP response to be returned with the specified status-code and with the message/trace written. For example,

    @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No such Account")  // 404
    public class AddressNotFoundException extends RuntimeException {
        // ...
    }
    

    And here is a controller method using it:

    @RequestMapping(value="/account/{id}", method=GET)
    public String showOrder(@PathVariable("id") long id, Model model) {
        Account account = accountServices.findAccountById(id);
    
        if (account == null) throw new AddressNotFoundException(id);
        model.addAttribute(account);
        return "accountDetail";
    }
    

    A familiar HTTP 404 response will be returned if the URL handled by this method includes an unknown account id.

    Hope this helps.