Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache Camel: Unable to get the Exception Body

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();
like image 976
rohan Avatar asked Dec 07 '16 01:12

rohan


People also ask

What is direct in camel?

The direct: component provides direct, synchronous invocation of any consumers when a producer sends a message exchange. This endpoint can be used to connect existing routes in the same camel context.

What is Apache Camel tutorial?

Apache Camel essentially provides an implementation of various EIPs. It makes integration easier by providing connectivity to a very large variety of transports and APIs. For example, you can easily route JMS to JSON, JSON to JMS, HTTP to JMS, FTP to JMS, even HTTP to HTTP, and connectivity to Microservices.

What is camel exchange?

Camel Exchange represents an abstraction for an exchange of messages which involves a request message and its corresponding reply or an exception message. It consists of the below components: Exchange ID – A unique ID that identifies the exchange.


1 Answers

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();
    }
});
like image 187
Cyäegha Avatar answered Oct 29 '22 20:10

Cyäegha