Reputation: 17
I'm new to Camel Apache and I'm having some troubles in the Exception handling. What I'm trying to do is catch the SalesforceException and from there I need to take different actions based on the statusCode.
For example, when the statusCode >= 500 I must try to redeliver the message. This is a technical error. When the statusCode < 500, I must combine the request & response and place it on the failureQueue.
So my question is : how can I try to redeliver the message in a choice definition? It doesn't seem possible to use the following options you can use on onException :
.handled(true).useOriginalMessage().maximumRedeliveries(3)
.redeliveryDelay(5000)
.logRetryAttempted(true)
.retryAttemptedLogLevel(LoggingLevel.WARN)
I also tried throwing new exceptions I defined myself so I can handle it from there but then it looks like the FatalFallbackErrorHandler takes over and I have no power as I can't handle it by myself. So my second question - if there's no answer to resending it in a choicedefinition - how can I handle it in a custom exception without the ErrorHandler taking over?
Here is my code :
onException()
.logStackTrace(true);
onException(SalesforceException.class)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
SalesforceException cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, SalesforceException.class);
exchange.setProperty("statusCode", cause.getStatusCode());
exchange.setProperty("response", cause.getMessage());
}
})
.choice()
.when(header("statusCode").isGreaterThanOrEqualTo(500))
// try to redeliverd the orginal message
.log(LoggingLevel.WARN, "{{logger}}", "Salesforce exception caught with statusCode >= 500")
.throwException(new SalesforceTechnicalException())
.otherwise()
// combine request & response and put on failurequeue
.log(LoggingLevel.WARN, "{{logger}}", "Salesforce exception caught with statusCode < 500, following message will be put on failure queue")
.throwException(new SalesforceFunctionalException())
.end();
onException(SalesforceTechnicalException.class)
//combine request & response and put on failurequeue
.transform(ExpressionBuilder.simpleExpression("{\"request\" : ${exchangeProperty.requestBody}, \"response\" : ${exchangeProperty.response}}"))
.to("log:{{logger}}?level=INFO&showHeaders=true")
.to("amqp:qFailure?exchangePattern=InOnly");
onException(SalesforceTechnicalException.class)
//try resending the orginal message to SF Rest API
.useOriginalMessage()
.handled(true)
.maximumRedeliveries(3)
.redeliveryDelay(5000)
.logRetryAttempted(true)
Upvotes: 1
Views: 935
Reputation: 2307
You should be able to use a pair of onException(SalesforceException.class) blocks and narrow each one with an onWhen(Predicate).
onException(SalesforceException.class)
.onWhen(new Predicate() {
@Override
public boolean matches(Exchange exchange) {
SalesforceException cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, SalesforceException.class);
return cause.getStatusCode() < 500;
}
})
.log("Handled here if statusCode < 500")
.useOriginalMessage()
.handled(true)
.maximumRedeliveries(3)
.redeliveryDelay(5000)
.logRetryAttempted(true);
onException(SalesforceException.class)
.onWhen(new Predicate() {
@Override
public boolean matches(Exchange exchange) {
SalesforceException cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, SalesforceException.class);
return cause.getStatusCode() >= 500;
}
})
.log("Handled here if statusCode >= 500")
.transform(ExpressionBuilder.simpleExpression("{\"request\" : ${exchangeProperty.requestBody}, \"response\" : ${exchangeProperty.response}}"))
.to("log:{{logger}}?level=INFO&showHeaders=true")
.to("amqp:qFailure?exchangePattern=InOnly");
Upvotes: 1