on 2025 Apr 15 3:59 PM
When an OData calls, after a multicast step (a single multicast step, not nested), the error details are suppressed when sending to Exception Handling.
i.e. OData Error
<error>
<code>SLS_LORD/033</code>
<message>The document is locked</message>
</error>
Error available in Exception Handling:
org.apache.camel.CamelExchangeException: Multicast processing failed for number 0. Exchange[55EE78BA9D8B2F2-0000000000000004]. Caused by: [com.sap.gateway.core.ip.component.odata.exception.OsciException - Bad Request : 400 : HTTP/1.1 ]
How do we get to the OData error in our error handling? The normal Groovy script can only return the Camel error, which is the Multicast processing error. It can't retrieve the OData error
Request clarification before answering.
Hi @EoinCollins
You can include the Groovy script in your "Exception Subprocess". Please find sample below.
import com.sap.gateway.ip.core.customdev.util.Message
// Version 1.0
// save attachments to log and build error email body
def Message processData(Message message) {
def map = message.getProperties()
def headers = message.getHeaders()
def add_to_log_property = message.getProperty("ErrorLogAttachments") ?: 'false'
def add_to_log = (add_to_log_property ==~ /(?i)(true|x)/)
def email_body = ''
def headers_text = ''
// get an exception java class instance
def ex = map.get('CamelExceptionCaught')
if (ex != null) {
// fill only minimal information into email body
email_body = "MPL ID: " + map.get("SAP_MessageProcessingLogID") + "\n"
email_body += "Correlation ID: " + headers.get("SAP_MplCorrelationId") + "\n"
email_body += "Timestamp: " + map.get("CamelCreatedTimestamp") + "\n"
exmap = ex.getProperties()
// an http adapter throws an instance of org.apache.camel.component.ahc.AhcOperationFailedException
if (ex.getClass().getCanonicalName().equals('org.apache.camel.component.ahc.AhcOperationFailedException')) {
if (add_to_log) {
// save the http error response as a log attachment
def messageLog = messageLogFactory.getMessageLog(message)
messageLog.addAttachmentAsString('ResponseBody', ex.getResponseBody(), 'text/plain')
}
message.setProperty('http.StatusCode', ex.getStatusCode())
message.setProperty('http.StatusText', ex.getStatusText())
message.setProperty('http.ResponseBody', ex.getResponseBody())
}
if (add_to_log) {
// add headers
headers.each{ k, v ->
headers_text += "${k}: ${v}" + "\n"
}
// save headers as a log attachment
def messageLog2 = messageLogFactory.getMessageLog(message)
messageLog2.addAttachmentAsString('Headers', headers_text, 'text/plain')
// save source payload as a log attachment
if( map.get("OriginalPayload") != null && map.get("OriginalPayload") != '' ) {
def messageLog3 = messageLogFactory.getMessageLog(message)
messageLog3.addAttachmentAsString('OriginalPayload', map.get("OriginalPayload"), 'text/plain')
}
// save payload as a log attachment
if( map.get("RequestPayload") != null && map.get("RequestPayload") != '' ) {
def messageLog4 = messageLogFactory.getMessageLog(message)
messageLog4.addAttachmentAsString('RequestPayload', map.get("RequestPayload"), 'text/plain')
}
// save payload as a log attachment
if (map.get("BatchErrorResponse") != null && map.get("BatchErrorResponse") != '' ) {
def messageLog5 = messageLogFactory.getMessageLog(message)
messageLog5.addAttachmentAsString('BatchResponseBody', map.get("BatchErrorResponse"), 'text/plain')
}
}
}
message.setBody(email_body)
return message
}Note: In this case, the handler prepares the data to send it via email, but you can leverage it and adjust it accordingly.
Regards,🖖🏻
Ricardo
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Ricardo,
Unfortunately, this do no work either. The problem we have is that Multicast is suppressing the error before sending it to the Exception Handler.
As we can see in this screenshot, the error happens within a Sequential Multicast. The body of the response is what I want to be able to read:
However, once we get into the Exception Handling, we do not have access to the org.apache.camel.component.ahc.AhcOperationFailedException, as expected in the your Groovy. Instead we get org.apache.camel.CamelExchangeException: Multicast processing failed for number 0.
This CamelExchangeException does not have the same detail within it.
If this call was not within a Multicast (unfortunately, it has to be) then your solution would be perfect. But Multicast is suppressing the error details and this is what I am trying to figure my way around.
Thank you,
Eoin
Hi @EoinCollins
I understand that you want to capture not just the camel error but also the information from the ODATA response to process in your error handling.
I am going to share two examples of how SAP handles these scenarios.
Scenario A: Calling ODATA in S/4HANA
Step 1: Call the ODATA API
Step 2: Capture some information from the response
Step 3: Use specific groovy to capture the corresponding information
Scenario B: Calling ODATA (Batch) in S/4HANA
Step 1: Prepare the Batch Request
Step 2: Call ODATA API
Step 3: Use Groovy to check for Errors
Step 4: Use Groovy to throw the error
I hope this answers your question and helps you to design a proper solution for your specific requirement.
Best regards, 🖖🏻
Ricardo
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Ricardo,
Neither of these are possible, because OData is failing with a 400 error, so iFlow processing ceases at that point. Exception handling is invoked and within exception handling, we have the camel error available, not the OData error.
We dont have the option to interrogate the OData response via Groovy, before it enters Exception Handling. If we had that option, your suggestion would work perfectly.
Thank you,
Eoin
| User | Count |
|---|---|
| 14 | |
| 7 | |
| 6 | |
| 5 | |
| 4 | |
| 3 | |
| 3 | |
| 3 | |
| 3 | |
| 3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.