🤖 Tutorial: How to use Gemini AI to Debug SAP CPI Errors Automatically 🤖
Body: Why settle for cryptic stack traces? I recently built a custom Exception Subprocess in SAP Integration Suite that catches failures and asks Google's Gemini AI to explain them in plain English.
Here is the exact step-by-step configuration I used to build the "CPI-GEMINI" flow:
Step 1: The Exception Subprocess Strategy I moved the error handling logic out of the main process into a dedicated Exception Subprocess. This ensures that any failure in the main "Happy Path" immediately triggers this recovery logic.
Step 2: Constructing the AI Prompt (Content Modifier) To talk to the API, we need to format the request perfectly. I used a Content Modifier with two key parts:
Headers: Set Content-Type to application/json and Authorization to your Google API Key.
Body: This is where the magic happens. I wrapped the standard ${exception.message} variable inside the required Gemini JSON schema: {"contents": [{"parts":[{"text": "In cpi iflow following error encounter:${exception.message}"}]}]}.
Step 3: Calling the Model (HTTP Adapter) I used the standard HTTP Receiver adapter to POST the payload to the Gemini 2.5 Flash endpoint.
Address: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
Method: POST.
Step 4: Handling the Response (JSON to XML & Filter) The AI response is a large JSON object. To extract just the answer:
JSON to XML Converter: I converted the response and added a custom root element named root.
Filter: I used an XPath expression to drill down to the exact text node: /root/candidates/content/parts/text.
Step 5: Logging the Insight (Groovy Script) Finally, I used a simple Groovy script to grab the filtered AI explanation and attach it to the Message Processing Log (MPL).
Code: messageLog.addAttachmentAsString("Error_Body_Payload", body, "text/plain").
The Result: Instead of just seeing "System Error," the monitoring log now contains an attachment where Gemini explains the likely cause of the failure based on the error context.
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="candidates">
<xs:complexType>
<xs:sequence>
<xs:element name="content">
<xs:complexType>
<xs:sequence>
<xs:element name="parts">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="text"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="role"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="finishReason"/>
<xs:element type="xs:float" name="avgLogprobs"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="usageMetadata">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:byte" name="promptTokenCount"/>
<xs:element type="xs:short" name="candidatesTokenCount"/>
<xs:element type="xs:short" name="totalTokenCount"/>
<xs:element name="promptTokensDetails">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="modality"/>
<xs:element type="xs:byte" name="tokenCount"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="candidatesTokensDetails">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="modality"/>
<xs:element type="xs:short" name="tokenCount"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="modelVersion"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>import com.sap.gateway.ip.core.customdev.util.Message
import com.sap.it.api.msglog.MessageLogFactory
def Message processData(Message message) {
// 1. Access the Message Log
def messageLog = messageLogFactory.getMessageLog(message)
// 2. Get the current Body as a String
// This captures whatever payload is currently in the flow (Error response or Request)
def body = message.getBody(String.class)
if (messageLog != null) {
// 3. Attach it to the Monitoring Log
// "Error_Body_Payload" is the name of the link that will appear in the Monitor
if (body != null && !body.isEmpty()) {
messageLog.addAttachmentAsString("Error_Body_Payload", body, "text/plain")
} else {
messageLog.addAttachmentAsString("Error_Body_Payload", "Body was empty.", "text/plain")
}
}
return message
}
Request clarification before answering.
| User | Count |
|---|---|
| 5 | |
| 4 | |
| 4 | |
| 3 | |
| 2 | |
| 2 | |
| 2 | |
| 2 | |
| 2 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.