Context
PR #560 fixes context-echo on the AdcpError raise path in serve.py and a2a_server.py. It does NOT touch dispatch.py. Need to verify the dispatcher's exception-wrap path doesn't bypass the new echo.
The concern
In src/adcp/server/serve.py:1809-1810:
except Exception as exc:
if DecisioningAdcpError is not None and isinstance(exc, DecisioningAdcpError):
return build_mcp_error_result(exc, params=kwargs) # type: ignore[return-value]
raise
The bare raise covers the non-AdcpError case. Two paths a non-AdcpError exception can take:
- Wrapped upstream as DecisioningAdcpError("INTERNAL_ERROR") by
dispatch.py:1163 (_internal_error_details wrap). In this case the exception reaching serve.py IS DecisioningAdcpError and the new echo path runs. ✅
- Re-raised as generic Exception through some other code path that skips the dispatch wrap (middleware-direct, executor-level, etc.). In this case the bare
raise propagates and the wire eventually carries an MCP-level error without context echo. ❌
What to verify
- Walk every code path between
platform.method() invocation and the serve.py:1798 except Exception to confirm non-AdcpError exceptions are always wrapped to DecisioningAdcpError("INTERNAL_ERROR") before they escape dispatch.
- If any path bypasses the wrap (test-controller, middleware short-circuit,
asgi_middleware raising), file a follow-up to add the echo at that catch site too.
Acceptance
A regression test that raises ValueError("oops") from a handler with a request context field and asserts the wire response carries that context (whether wrapped as INTERNAL_ERROR or surfaced as a transport-level error).
Context
PR #560 fixes context-echo on the AdcpError raise path in
serve.pyanda2a_server.py. It does NOT touchdispatch.py. Need to verify the dispatcher's exception-wrap path doesn't bypass the new echo.The concern
In
src/adcp/server/serve.py:1809-1810:The bare
raisecovers the non-AdcpError case. Two paths a non-AdcpError exception can take:dispatch.py:1163(_internal_error_detailswrap). In this case the exception reachingserve.pyISDecisioningAdcpErrorand the new echo path runs. ✅raisepropagates and the wire eventually carries an MCP-level error without context echo. ❌What to verify
platform.method()invocation and theserve.py:1798except Exceptionto confirm non-AdcpError exceptions are always wrapped toDecisioningAdcpError("INTERNAL_ERROR")before they escape dispatch.asgi_middlewareraising), file a follow-up to add the echo at that catch site too.Acceptance
A regression test that raises
ValueError("oops")from a handler with a requestcontextfield and asserts the wire response carries thatcontext(whether wrapped asINTERNAL_ERRORor surfaced as a transport-level error).