cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Sequential Multicast suppressing error details

EoinCollins
Explorer
0 Likes
1,750

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

SAP Integration Suite 

 

Accepted Solutions (0)

Answers (2)

Answers (2)

MAVR
Product and Topic Expert
Product and Topic Expert

Hi @EoinCollins 

You can include the Groovy script in your "Exception Subprocess". Please find sample below.
Screenshot 2025-04-16 at 4.25.35 PM.png

 

Screenshot 2025-04-16 at 4.25.46 PM.png

 

Screenshot 2025-04-16 at 4.26.17 PM.png

 

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  

EoinCollins
Explorer
0 Likes

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:

EoinCollins_0-1744876429613.png

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.

EoinCollins_1-1744876552622.png

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

MAVR
Product and Topic Expert
Product and Topic Expert

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

Screenshot 2025-04-15 at 11.17.26 PM.png

Step 1: Call the ODATA API

Step 2: Capture some information from the response 
Screenshot 2025-04-15 at 11.17.36 PM.png

Step 3: Use specific groovy to capture the corresponding information
Screenshot 2025-04-15 at 11.16.58 PM.png

Scenario B: Calling ODATA (Batch) in S/4HANA

Step 1: Prepare the Batch Request
Screenshot 2025-04-15 at 11.28.26 PM.png

 Step 2: Call ODATA API
Screenshot 2025-04-15 at 11.31.19 PM.png

Step 3: Use Groovy to check for Errors
Screenshot 2025-04-15 at 11.27.24 PM.png

 Step 4: Use Groovy to throw the error
Screenshot 2025-04-15 at 11.29.37 PM.pngScreenshot 2025-04-15 at 11.29.23 PM.png

I hope this answers your question and helps you to design a proper solution for your specific requirement.

Best regards, 🖖🏻
Ricardo

 

 

 

EoinCollins
Explorer
0 Likes

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.

EoinCollins_0-1744789308085.png

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