OData Gateway Part 10: Debugging OData Services
Debug Gateway services end to end: external (HTTP) breakpoints for the right user and system, /IWFND/ERROR LOG and /IWBEP/ERROR LOG with replay, payload traces in /IWFND/TRACES, the browser network tab, sap-statistics for timing, application logging in DPC EXT, and a systematic workflow from symptom to root cause.
Explanation
📌 KEY POINTS
✅ OData requests come over HTTP, so session breakpoints do not stop them — set external breakpoints for the user who sends the request (in a hub: in the backend, for the user the trusted RFC passes).
✅ /IWFND/ERROR_LOG (frontend) and /IWBEP/ERROR_LOG (backend) show failed requests with exception, message and call stack; "Replay" re-executes the request in the Gateway client.
✅ /IWFND/TRACES records full request and response payloads for a user — ideal for "what exactly did the app send?".
⚠️ Always reproduce with the same user, same system and same payload. Many "cannot reproduce" cases are different authorizations, different key formats or cached metadata.
━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE
Parts 1–9 built and hardened the service. This final part is how you find problems fast.
━━━━━━━━━━━━━━━━━━━━
▶ 1. EXTERNAL BREAKPOINTS
- In ADT or SE80: set breakpoint → type external/HTTP, for user X.
- Hub: set it in the backend system; with trusted RFC the backend user is the end user.
- Debugger settings: user must have debug authorization (S_DEVELOP with DEBUG) — in production only with strict approval.
━━━━━━━━━━━━━━━━━━━━
▶ 2. ERROR LOGS
- /IWFND/ERROR_LOG: service, entity set, HTTP method, error text, request URI; buttons for backend log, call stack, and Replay (opens Gateway client with the same request).
- /IWBEP/ERROR_LOG: backend view with ABAP exception details and source position.
- Both keep entries for a configured period.
━━━━━━━━━━━━━━━━━━━━
▶ 3. PAYLOAD TRACE
- /IWFND/TRACES: Configuration → user, service, level; Payload Trace tab shows request and response bodies.
- Use it to verify filters, keys and JSON sent by the UI; switch off after analysis.
━━━━━━━━━━━━━━━━━━━━
▶ 4. BROWSER AND UI
- F12 → Network: the OData call, URL, status, response body, sap-message header.
- URL parameter sap-statistics=true (or header) returns server timing per request.
- In UI5 apps: debug mode and the Diagnostics window show the requests too.
━━━━━━━━━━━━━━━━━━━━
▶ 5. LOGGING IN CODE
- Application log (SLG1) via BAL_LOG_CREATE, BAL_LOG_MSG_ADD, BAL_DB_SAVE for business-relevant failures.
- Keep logs concise; never log personal data unnecessarily.
━━━━━━━━━━━━━━━━━━━━
▶ 6. WORKFLOW
- Get the exact request (browser F12 or /IWFND/TRACES).
- Check /IWFND/ERROR_LOG and backend log.
- Replay in the Gateway client as the same user.
- External breakpoint in the DPC_EXT method.
- Fix, clean caches if the model changed, retest the saved test cases.
━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP
- Force an error in your service (e.g. wrong key) and find it in /IWFND/ERROR_LOG.
- Replay it and set an external breakpoint in GET_ENTITY.
- Enable /IWFND/TRACES for your user and inspect a POST payload.
- Add an application log entry for BAPI errors and view it in SLG1.
✅ CHECKPOINT: you can take any OData failure from symptom to root cause with logs, traces and the debugger.
Code example
* ===== STEP 1: debugging checklist =====* 1 Browser F12 / Network -> copy request URL, method, payload, status* 2 /IWFND/ERROR_LOG -> error text, backend log, call stack, Replay* 3 /IWBEP/ERROR_LOG -> ABAP exception and source position (backend)* 4 /IWFND/TRACES -> payload trace for the user (switch off afterwards)* 5 External breakpoint in DPC_EXT for the requesting user* 6 Timing: add ?sap-statistics=true to the request * ===== STEP 2: application log in DPC_EXT (SLG1) - private method =====METHOD log_bapi_errors.* IMPORTING it_return TYPE bapiret2_t DATA: ls_log TYPE bal_s_log, lv_handle TYPE balloghndl, ls_msg TYPE bal_s_msg, ls_return TYPE bapiret2, lt_handle TYPE bal_t_logh. ls_log-object = 'ZSALES'. "SLG0 object ls_log-subobject = 'ODATA'. ls_log-extnumber = 'SalesOrderSet'. ls_log-aluser = sy-uname. CALL FUNCTION 'BAL_LOG_CREATE' EXPORTING i_s_log = ls_log IMPORTING e_log_handle = lv_handle EXCEPTIONS OTHERS = 1. CHECK sy-subrc = 0. * ===== STEP 3: copy BAPI messages into the log ===== LOOP AT it_return INTO ls_return. CLEAR ls_msg. ls_msg-msgty = ls_return-type. ls_msg-msgid = ls_return-id. ls_msg-msgno = ls_return-number. ls_msg-msgv1 = ls_return-message_v1. ls_msg-msgv2 = ls_return-message_v2. CALL FUNCTION 'BAL_LOG_MSG_ADD' EXPORTING i_log_handle = lv_handle i_s_msg = ls_msg EXCEPTIONS OTHERS = 1. ENDLOOP. * ===== STEP 4: save ===== APPEND lv_handle TO lt_handle. CALL FUNCTION 'BAL_DB_SAVE' EXPORTING i_t_log_handle = lt_handle EXCEPTIONS OTHERS = 1.ENDMETHOD.* Note: in a changeset, the log may need its own commit (BAL_DB_SAVE with* i_2th_connection) so it survives a rollback.Real project scenario
A Fiori save failed for one plant in production only; developers could not reproduce it in quality. /IWFND/ERROR_LOG showed "Material not maintained for plant", but the payload in the error log was truncated.
Support enabled /IWFND/TRACES for the affected user for ten minutes and captured the POST: the app sent the plant with a trailing space from a custom value help. Replaying the exact payload in the Gateway client reproduced the error, an external breakpoint in CREATE_ENTITY confirmed it, and the fix (condense input + value help correction) went live the same day.
Common mistakes
- Setting session breakpoints for HTTP requests.
- Setting breakpoints on the hub instead of the backend.
- Testing with a different user than the one reporting the issue.
- Leaving payload traces switched on.
- Logging full personal data in application logs.
Best practices
- Start from the exact request (F12 or /IWFND/TRACES).
- Use error logs and Replay before the debugger.
- External breakpoints for the requesting user in the right system.
- Application logs for business-relevant failures.
- Debugging in production only with approval and time limits.
Interview angle
Questions: "How do you debug an OData call from Fiori?", "Where do you find Gateway errors?", "How do you see the payload the app sent?"
Strong answer: external breakpoint for the requesting user in the backend DPC_EXT (backend in hub scenarios); /IWFND/ERROR_LOG and /IWBEP/ERROR_LOG with call stack and Replay in /IWFND/GW_CLIENT; /IWFND/TRACES payload trace; browser F12 network and sap-statistics; application logs in SLG1; reproduce with same user, system and payload.
Practice this lesson
Quick check
1. A Fiori OData call does not stop at a breakpoint you set in DPC_EXT. What is the most likely fix?
2. Which transaction records the full request and response payload of OData calls for a given user?
3. Frontend error log is:
Interview questions
1. Where do you check errors for a failing OData service?
Answer it in your own words first, then compare.
2. A service works when you test it in the Gateway client, but fails when called from the Fiori app. How do you find the difference?
Answer it in your own words first, then compare.
Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.
More lessons in this topic
- OData Gateway Part 1: OData Basics and Your First SEGW Service
- OData Gateway Part 2: SEGW vs RAP — Two Ways to Build OData
- OData Gateway Part 3: $expand, Navigation, Deep Insert and $batch
- OData Gateway Part 4: Gateway Architecture — Hub vs Embedded
- OData Gateway Part 5: Service Registration, $metadata and Gateway Client Testing
- OData Gateway Part 6: GET_ENTITY and Key Handling
- OData Gateway Part 7: GET_ENTITYSET with Filters, Paging and Sorting
- OData Gateway Part 8: CREATE_ENTITY, UPDATE_ENTITY and DELETE_ENTITY