Skip to content

runReport times out in WebSocket/APC context — REPORT_SERVICE uses sync SUBMIT #115

@AnOffeElco

Description

@AnOffeElco

runReport times out in WebSocket/APC context — REPORT_SERVICE uses sync SUBMIT

Summary

The debug RUN_REPORT MCP tool times out when routed to ZCL_VSP_REPORT_SERVICE->handle_run_report on a stateful APC handler. The root cause is that SUBMIT ... AND RETURN is invalid in an APC stateful session (raises APC_ILLEGAL_STATEMENT), and the existing async path in ZCL_VSP_RFC_SERVICE->handle_run_report is fire-and-forget while the MCP client waits synchronously.

Environment

  • vsp version: deployed ABAP side from main branch (src/ directory, version 2.3.0 in welcome frame)
  • SAP: S/4HANA 2023, release 758, kernel 75I
  • APC endpoint: /sap/bc/apc/sap/zadt_vsp (stateful)

Reproduce

Deploy the repo's src/ content, then call either:

SAP(action="debug", target="RUN_REPORT", params={"report": "ZANY_REPORT"})
SAP(action="debug", target="RUN_REPORT", params={"report": "ZANY_ALV", "capture_alv": true})

Observed:

RunReport failed: timeout waiting for report response

Expected: either the report result (for capture_alv=true) or a completion status.

Root cause analysis

Two separate code paths, both broken for this use case:

  1. ZCL_VSP_REPORT_SERVICE->handle_run_report (domain report)

    • Does direct SUBMIT (lv_report) AND RETURN
    • Invalid in APC stateful handler → raises APC_ILLEGAL_STATEMENT at runtime
    • Exception is caught by the outer TRY, but then the process is already in a bad state — on our system the response never arrives at the client (likely because the APC session is torn down)
  2. ZCL_VSP_RFC_SERVICE->handle_run_report (domain rfc)

    • Uses CALL FUNCTION 'RFC_ABAP_INSTALL_AND_RUN' STARTING NEW TASK — returns immediately with a task id
    • No callback, no result wiring back to the client → the MCP client has nothing to wait on and times out

So whichever domain the MCP client routes to, it can't get a result synchronously.

Suggested fix

Request/poll pattern:

  1. runReport → schedule via STARTING NEW TASK ... PERFORMING on_end_of_task, return {"status":"started","requestId":"..."} immediately
  2. on_end_of_task writes the result (subrc, ALV rows, runtime) into a shared memory / shared buffer / DB table keyed by requestId
  3. New action getReportResult with {"requestId":"..."} → returns the persisted result (or {"status":"running"})
  4. Optional: push result via mo_message_manager->send( ) when the APC session is still alive — but that requires keeping a reference to the message manager in the async context, which is hairy

Alternatively, for the ALV-capture use case, wrap the SUBMIT into a separate work process via a more controlled async mechanism (e.g. cl_bgmc_process_factory) and return a handle.

Either way, the MCP client (RunReport handler) needs a matching two-step protocol.

Workaround

None from the client side. Users currently can't run reports via the MCP.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions