Now accepting guest editorial from SAP, Oracle, Workday and ServiceNow practitioners.Pitch a guide
The Sign-Off Table

Lesson 5 of 6

$batch and error payloads

10 min

Listen to this lesson

0:00 / 7:44

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

Batch requestPOST to <service root>/$batch with Content-Type multipart/mixed; boundary=batch_1, plus the CSRF token
Retrieve partsEach GET is its own MIME part (application/http); not allowed inside a change set
Change setA nested multipart part with its own boundary; holds POST, PATCH/MERGE, PUT, DELETE; all or nothing
OperationsEach operation is a complete HTTP request: method, relative URL, headers, body
Layers of an OData V2 $batch request as SAP Gateway processes it.
The Sign-Off Table · thesignofftable.com/academy/sap-tst-211

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.

Read every part: change set A committed, change set B rolled back as one unit, while the outer status was still 202.
The Sign-Off Table · thesignofftable.com/academy/sap-tst-211
A Fiori save is usually one $batch; to reproduce a user's defect, capture that batch in the browser's developer tools and replay it.
The Sign-Off Table · thesignofftable.com/academy/sap-tst-211

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 contentWhat the tester does with it
error.codeA message class and number, for example from the sales or BP message classAssert on it in negative tests; it is stabler than the text
error.message.valueThe first or main message textShow it in the defect; do not assert long texts exactly
innererror.errordetails[].severityerror, warning or infoCount errors versus warnings
innererror.errordetails[].targetThe property the message refers toCheck the right field was blamed
innererror.transactionidAn ID shared with the system error logPaste it into the defect for /IWFND/ERROR_LOG

Parts of an SAP Gateway V2 error payload a tester should use.

StatusTypical meaning in SAP APIsWhere to look next
400 Bad RequestMalformed request or business validation failed (missing field, invalid value)errordetails: every message, not just the first
403 ForbiddenCSRF token problem or missing authorizationX-CSRF-Token header; STAUTHTRACE on the system
404 Not FoundWrong path, inactive service, wrong key or clientMetadata, service activation, sap-client
405 Method Not AllowedVerb not supported for this entityMetadata annotations
412 / 428ETag mismatch / ETag requiredRe-read the entity; add If-Match
500 Internal Server ErrorUnhandled 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?

Key points
  • 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. 1. What happens when one operation in a change set fails?

  2. 2. Which request type may not appear inside a change set?

  3. 3. Where do SAP services return warnings on a successful call?

  4. 4. Which transaction shows the gateway hub error log?