Skip to content

feat(agentgateway): enrich AGW execution flow logs - #292

Open
ricardosrib wants to merge 5 commits into
mainfrom
feat/enhance-error-logs
Open

feat(agentgateway): enrich AGW execution flow logs#292
ricardosrib wants to merge 5 commits into
mainfrom
feat/enhance-error-logs

Conversation

@ricardosrib

Copy link
Copy Markdown
Contributor

Description

Improves error logging in the Agent Gateway MCP client.

1. Add JsonRpcError.parse for HTTP error bodies

When AGW returns a non-2xx response with a JSON-RPC body, the error code and message are now extracted and shown inline instead of dumping the raw response text.

2. Guard exc.response.text with try/except httpx.ResponseNotRead

streamable_http_client calls raise_for_status() before buffering the response body. Accessing .text in that state raised ResponseNotRead, crashing the SDK with no error log produced.

3. Add McpError branch to _log_mcp_server_error

AGW returns HTTP 200 with a JSON-RPC error in the SSE body for protocol-level failures. The MCP client surfaces these as McpError, which previously fell through to the generic else branch and logged only — skipping with no error details.

4. Improve else branch

The exception type and message are now included on the log line itself. The full traceback is still attached via exc_info.

5. Add URL to tool warnings/errors in call_mcp_tool_lob and call_mcp_tool_customer

6. Log User auth token obtained at INFO in all three get_user_auth return paths

Confirms the token was successfully obtained and consumed across the customer and LoB flows.

7. Remove duplicate get_user_auth call in list_mcp_tools LoB branch

The LoB branch was calling get_user_auth twice, causing a redundant duplicate INFO log per invocation.

8. Replace implicit duplicate get_user_auth in call_mcp_tool LoB branch with an explicit error

Raises AgentGatewaySDKError when user_token is missing, making the requirement explicit instead of relying on a side-effect call.


Logs before/after

1. HTTPStatusError + JSON-RPC body

# Before
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' (HTTP 500): {"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal Server Error"}}

# After
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — https://eu12.access.sapdas-dev.cloud.sap/v1/mcp/test-ord-id/test-gt-id returned HTTP 500 [JSON-RPC -32603]: Internal Server Error

2. HTTPStatusError + plain body

# Before
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' (HTTP 401): Unauthorized — invalid token

# After
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — https://eu12.access.sapdas-dev.cloud.sap/v1/mcp/test-ord-id/test-gt-id returned HTTP 401: Unauthorized — invalid token

3. HTTPStatusError + ResponseNotRead

# Before — SDK crashes, no ERROR log produced
Traceback (most recent call last):
  File "_lob.py", line 309, in _log_mcp_server_error
    exc.response.text[:500]
httpx.ResponseNotRead

# After
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — https://eu12.access.sapdas-dev.cloud.sap/v1/mcp/test-ord-id/test-gt-id returned HTTP 500: (response body not available)

4. McpError

# Before — error code and message lost
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — skipping

# After
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — JSON-RPC -32600: Validation failure for params.targetMcpServerId: isNoValidOrdId

5. BaseExceptionGroup wrapping McpError

# Before — McpError details lost after unwrap
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — skipping

# After
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — JSON-RPC -32700: Parse error

6. Else branch (unexpected exception)

# Before — no exception type on the log line
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — skipping
Traceback (most recent call last):
    raise RuntimeError("unexpected internal failure")
RuntimeError: unexpected internal failure

# After
ERROR:..._lob:Failed to load tools from fragment 'sap-managed-runtime-agw-mcp-test-fragment' — RuntimeError: unexpected internal failure
Traceback (most recent call last):
    raise RuntimeError("unexpected internal failure")
RuntimeError: unexpected internal failure

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)

How to Test

  1. Run against a LoB tenant with a valid user token:
    client = create_client(tenant_subdomain="<subdomain>")
    tools = await client.list_mcp_tools(user_token="<ias_id_token>")
  2. Check that User auth token obtained — gateway: '<url>' appears exactly once at INFO level.
  3. If any MCP fragment is misconfigured (invalid ORD ID), confirm the log shows JSON-RPC -32600: <message> instead of — skipping.
  4. To exercise all _log_mcp_server_error branches, import and call it directly with httpx.HTTPStatusError, McpError, and a generic RuntimeError — each should produce a distinct, self-contained ERROR log line.

@ricardosrib
ricardosrib requested a review from a team as a code owner August 28, 2026 18:09
@ricardosrib ricardosrib changed the title feat: Enrich AGW execution flow logs feat: enrich AGW execution flow logs Aug 28, 2026
@ricardosrib ricardosrib changed the title feat: enrich AGW execution flow logs feat: enrich agw execution flow logs Aug 28, 2026
body = None
rpc_error = JsonRpcError.parse(body) if body else None
if rpc_error:
logger.error(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm, is this the logger from core that Jean implemented?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is plain logger from the Python standard library

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use the one from our telemetry module, can you check?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you referring to _provider.py? That's only needed when you want these logs to flow through OTel rather than just printing to the console. What's the expected logging behavior here?

@NicoleMGomes

Copy link
Copy Markdown
Contributor

Great work!

@ricardosrib ricardosrib changed the title feat: enrich agw execution flow logs feat(agentgateway): enrich AGW execution flow logs Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants