Reputation: 233
We have the below XML configuration for a rest service and Oracle Stored Proc. The use case is about handling Oracle SP errors.
When the Oracle SP throws error, we need to achieve 2 things:
we need to send a json response back to the client in the format {"status": false,"message": "Oracle SP error payload"}
Send an email out.
The configuration is working as expected when Oracle SP throws error. But when the email send fails ( gave a wrong host), client is receiving error in the below format. The Oracle SP error message is not sent back.
---- Json message received by client when email send fails:------
{
"timestamp": 1501639940143,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.messaging.MessagingException",
"message": "failure occurred in error-handling flow; nested exception is org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.integration.handler.MessageHandlerChain#0$child#2.handler]; nested exception is org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Unknown SMTP host: xxx.com;..",
"path": "/init/5c82d1f4-e550-4bb1-be9c-8d0ddbc7f4401/NEW"
}
How do I send response in the expected json format - {"status": false,"message": Oracle SP error payload}?
Also how to handle the email send error.i.e may be how to store the email error in a DB table?
<int:channel id="spOutClobChannel"/>
<int:publish-subscribe-channel id="gatewayErrorChannel"/>
<int-http:inbound-gateway
request-channel="gatewayInitChannel"
error-channel="gatewayErrorChannel"
supported-methods="GET"
path="/init/{refId}/{refStatus}"
payload-expression="#pathVariables.refStatus">
<int-http:header name="UNIQUE_PROCESS_ID" expression="#pathVariables.refId"/>
</int-http:inbound-gateway>
<int-jdbc:stored-proc-outbound-gateway
id="sp-get-data"
data-source="dataSource"
request-channel="gatewayInitChannel"
reply-channel="spOutClobChannel".... >
...
...
</int-jdbc:stored-proc-outbound-gateway>
<int:transformer input-channel="spOutClobChannel" expression='{"status": true, "message": "RECEIVED"}'/>
<int:transformer input-channel="gatewayErrorChannel" expression='{"status": false,"message": payload.message}'/>
<int:transformer expression="payload.failedMessage.headers['UNIQUE_PROCESS_ID']"
input-channel="gatewayErrorChannel" output-channel="appEmailChannel"/>
<int:chain input-channel="appEmailChannel" >
<int-mail:header-enricher>
<int-mail:from value="${email.from}"/>
<int-mail:to value="${email.to}"/>
<int-mail:subject value="${email.subject}"/>
<int-mail:content-type value="text/html"/>
</int-mail:header-enricher>
<int-mail:outbound-channel-adapter host="${email.host}" />
</int:chain>
Upvotes: 2
Views: 1177
Reputation: 121552
To avoid errors thrown from the appEmailChannel
flow, plus get a gain do not wait for the successful email shipment, it would be better to add to your gatewayErrorChannel
an executor
configuration. This way all the subscribers to this publish-subscriber channel will be performed in parallel and in their own threads. Therefore any exception in those threads won't impact the reply to the <int-http:inbound-gateway>
which you've done with the
<int:transformer input-channel="gatewayErrorChannel" expression='{"status": false,"message": payload.message}'/>
Also how to handle the email send error.i.e may be how to store the email error in a DB table?
With this goal you can use ExpressionEvaluatingRequestHandlerAdvice
with its trapException = true
and failureChannel
properties.
This advice can be configured with the request-handler-advice-chain
sub-element.
See Reference Manual and Sample on the matter.
Upvotes: 1