Apache Camel: Unable to get the Exception Body
Asked Answered
D

1

8

Whenever there is normal flow in my Camel Routes I am able to get the body in the next component. But whenever there is an exception(Http 401 or 500) I am unable to get the exception body. I just get a java exception in my server logs. I have also tried onException().. Using that the flow goes into it on error, but still I do not get the error response body that was sent by the web service(which I get when using POSTMAN directly), I only get the request in the body that I had sent to the web service.

Also adding the route:

from("direct:contractUpdateAds")
        .to("log:inside_direct:contractUpdateAds_route_CompleteLog?level=INFO&showAll=true&multiline=true")
        .streamCaching()
        .setHeader(Exchange.HTTP_METHOD, constant("POST"))
        .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
        .log("before calling ADS for ContractUpdate:\nBody:${body}")
        .to("{{AdsContractUpdateEndpoint}}")
        .log("after calling ADS for ContractUpdate:\nBody:${body}")
        .convertBodyTo(String.class)
        .end();
Dubose answered 7/12, 2016 at 1:40 Comment(3)
You should mention which component you use to make the HTTP call (camel-http, camel-http4, camel-jetty...).Arenicolous
I was using camel-httpDubose
Can you provide the code for the whole flow? Also, how are you trying to fetch the exception body?Eamon
J
17

Option 1: handle failure status codes yourself

The throwExceptionOnFailure=false endpoint option (available at least for camel-http and camel-http4 endpoints) is probably what you want. With this option, camel-http will no longer consider an HTTP Status >= 300 as an error, and will let you decide what to do - including processing the response body however you see fit.

Something along those lines should work :

from("...")
.to("http://{{hostName}}?throwExceptionOnFailure=false")
.choice()
    .when(header(Exchange.HTTP_RESPONSE_CODE).isLessThan(300))
        // HTTP status < 300
        .to("...")
    .otherwise()
        // HTTP status >= 300 : would throw an exception if we had "throwExceptionOnFailure=true"
        .log("Error response: ${body}")
        .to("...");

This is an interesting approach if you want to have special handling for certains status codes for example. Note that the logic can be reused in several routes by using direct endpoints, just like any other piece of Camel route logic.

Option 2 : Access the HttpOperationFailedException in the onException

If you want to keep the default error handling, but you want to access the response body in the exception handling code for some reason, you just need to access the responseBody property on the HttpOperationFailedException.

Here's an example:

onException(HttpOperationFailedException.class)
.process(new Processor() {
    @Override
    public void process(Exchange exchange) throws Exception {
        // e won't be null because we only catch HttpOperationFailedException;
        // otherwise, we'd need to check for null.
        final HttpOperationFailedException e =
                exchange.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class);
        // Do something with the responseBody
        final String responseBody = e.getResponseBody();
    }
});
Judicious answered 7/12, 2016 at 15:1 Comment(2)
Thanks @Cyaegha it works. Is there any other way to actually get the error response body on the .onException(). Because otherwise I need to separately apply this condition on each calls..Dubose
I thought it wasn't possible, but looking at the code, I now notice that the HttpOperationFailedException has a responseBody property, which gets populated with (obviously) the response body... I'm going to edit my answer.Arenicolous

© 2022 - 2024 — McMap. All rights reserved.