Lesson 5 of 6
$batch and error payloads
10 min
Listen to this lesson
SAP Fiori apps rarely send one request at a time. They bundle reads and changes into a single $batch request, and many interfaces do the same. A tester who can read a batch request and its response can reproduce what an app really sends and see exactly which part failed. This lesson also covers error payloads, because in a batch the outer status says almost nothing.
How a batch is built
SAP's Gateway documentation describes a change set as an atomic, all-or-nothing unit of work: the framework commits at the end of the change set, and providers may not commit in between. Responses come back in the same order as the requests, in a multipart/mixed body whose boundary can differ from yours. The outer response is normally 202 Accepted even when parts inside failed. A test that checks only the outer status is not testing anything.
To see what an app really sends, open the browser developer tools on the Network tab, filter for $batch, perform the action, and copy the request payload. That payload, with the user's session replaced by a test user, becomes a precise reproduction for the defect. It is also the best source for the batch patterns your API tests should cover.
Designing change sets on purpose
- Group what must succeed together in one change set, for example a header change and its dependent item change.
- Separate independent changes into their own change sets, so one bad record does not roll back the others.
- Watch service limits. SAP's documentation notes that a provider may allow only one operation per change set or reject change sets; SAP community threads also report problems when the same document appears in several operations. Test the pattern the real client uses.
- Do not rely on Content-ID references between operations unless you have confirmed the service and release support them.
Reading error payloads
SAP Gateway returns errors as JSON (or XML) with a structure testers should learn by heart. In V2: error.code (for example a message class and number), error.message.value (the text), and error.innererror.errordetails, a list of all messages with their severity and target property. V4 uses error.code, error.message and error.details. Warnings and information messages on successful calls arrive in the sap-message response header, which most clients hide unless you look.
| Field (V2) | Example content | What the tester does with it |
|---|---|---|
| error.code | A message class and number, for example from the sales or BP message class | Assert on it in negative tests; it is stabler than the text |
| error.message.value | The first or main message text | Show it in the defect; do not assert long texts exactly |
| innererror.errordetails[].severity | error, warning or info | Count errors versus warnings |
| innererror.errordetails[].target | The property the message refers to | Check the right field was blamed |
| innererror.transactionid | An ID shared with the system error log | Paste it into the defect for /IWFND/ERROR_LOG |
Parts of an SAP Gateway V2 error payload a tester should use.
| Status | Typical meaning in SAP APIs | Where to look next |
|---|---|---|
| 400 Bad Request | Malformed request or business validation failed (missing field, invalid value) | errordetails: every message, not just the first |
| 403 Forbidden | CSRF token problem or missing authorization | X-CSRF-Token header; STAUTHTRACE on the system |
| 404 Not Found | Wrong path, inactive service, wrong key or client | Metadata, service activation, sap-client |
| 405 Method Not Allowed | Verb not supported for this entity | Metadata annotations |
| 412 / 428 | ETag mismatch / ETag required | Re-read the entity; add If-Match |
| 500 Internal Server Error | Unhandled error in the backend | /IWFND/ERROR_LOG and /IWBEP/ERROR_LOG on the system |
Status codes and the next place to look.
On Contoso's Private Edition systems, Theo's team reads /IWFND/ERROR_LOG (the gateway hub error log) and /IWBEP/ERROR_LOG (the backend error log) to see the full error context, and uses /IWFND/GW_CLIENT to replay a request inside the system. Testers attach the transaction ID from the error log to the defect, so the developer sees the same failure.
What would you do?
A nightly interface test sends one $batch with 20 address changes for different business partners in a single change set. It returns 202. In CMQ, none of the 20 addresses changed. What is the best explanation and fix?
- A $batch is a multipart POST; change sets are nested and atomic; GETs sit outside change sets.
- The outer 202 says nothing; assert on every part.
- Error payloads carry code, message and details; read all of errordetails and the sap-message header.
- On the system, /IWFND/ERROR_LOG, /IWBEP/ERROR_LOG and /IWFND/GW_CLIENT give the full picture.
Check your understanding · not graded
Lesson check
1. What happens when one operation in a change set fails?
2. Which request type may not appear inside a change set?
3. Where do SAP services return warnings on a successful call?
4. Which transaction shows the gateway hub error log?