Conversation
…s/retry_after, catch decisioning AdcpError (closes #530) - `_send_adcp_error` now uses `_extract_structured_fields` from translate.py (introduced in #525) to populate the full adcp_error envelope: code, message, recovery, field, details, retry_after, suggestion. - `execute()` adds a second `except Exception` branch that catches decisioning-layer `AdcpError` (separate hierarchy from `adcp.exceptions.ADCPError`) and routes it through `_send_adcp_error` instead of the generic "Skill execution failed" text path. - Drop now-unused `ADCPTaskError` and `STANDARD_ERROR_CODES` imports. - Tests: parametrized over MEDIA_BUY_NOT_FOUND, PACKAGE_NOT_FOUND, BUDGET_TOO_LOW, TERMS_REJECTED; decisioning AdcpError with retry_after; end-to-end execute() → DataPart round-trip for both paths. https://claude.ai/code/session_019DMGxsA43mtT7QTRiNipBM
…sport parity Mirror build_mcp_error_result: recovery is always included in the A2A DataPart adcp_error dict (no falsy guard), matching the MCP path where recovery is a required key per transport-errors.mdx §A2A Binding. https://claude.ai/code/session_019DMGxsA43mtT7QTRiNipBM
Contributor
Author
|
Superseded by #536 (feat(server/a2a): structured error parity with MCP — emit field/details/retry_after, catch decisioning AdcpError), already merged to main. |
Contributor
Author
|
Acknowledged — #536 supersedes this PR and is already merged to main. No further action needed here. Triaged by Claude Code. Session: https://claude.ai/code/session_0189ZzC2Brh3uWR3b8fq1Xiv Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #530
Summary
The A2A transport had two parity gaps vs. the MCP structured-error path shipped in #525:
execute()only caughtadcp.exceptions.ADCPError— decisioning-layeradcp.decisioning.types.AdcpError(raised byDecisioningPlatformadopters) fell into the genericexcept Exceptionpath and emitted a plain "Skill execution failed" text message with no structured envelope._send_adcp_erroronly emittedcode/message/recovery/suggestion— thefield,details, andretry_afterfields were dropped even when the raised error carried them, breaking wire-conformance for A2A storyboard structured-error assertions.This PR:
except Exceptionbranch inexecute()that lazy-importsAdcpErrorfromadcp.decisioning.types(matching the pattern intranslate.py) and routes it through_send_adcp_error._send_adcp_errorto delegate to_extract_structured_fieldsfromtranslate.py(introduced in feat(server): MCP error responses populate structuredContent.adcp_error (closes #509) #525), producing the full{code, message, recovery, field, suggestion, details, retry_after}envelope — and always emittingrecoveryunconditionally to match the MCP path (transport-errors.mdx §A2A Binding).ADCPTaskErrorandSTANDARD_ERROR_CODESimports.What tested
pytest tests/test_a2a_server.py— 47 passed (7 new tests added)pytest tests/test_server_idempotency.py— 45 passed (existing A2A conflict test still green)pytest tests/(non-integration, excluding 3 pre-existing missing-dep failures) — 3302 passed, 18 skippedruff check src/adcp/server/a2a_server.py— cleanmypy src/adcp/server/a2a_server.py— no new errors (pre-existing a2a/protobuf stub gaps unchanged)Pre-PR review
_DecAdcpErrorimport insideexceptis redundant with_extract_structured_fields's own lazy import (harmless, Python module cache); (2)exc: Anyon_send_adcp_errorexposes a potential silentTypeErrorfor future callers (internal callers are guarded); (3) preferDecisioningAdcpErrorover_DecAdcpErrorfor local var naming. All nits deferred.recoverywas guarded byif recovery:(could omit on falsy string) vs. MCP path which emits it unconditionally. Fixed in commitc4f01a2by moving"recovery": recoveryinto the base dict literal. Wire shape now fully matches transport-errors.mdx §A2A Binding.Session: https://claude.ai/code/session_019DMGxsA43mtT7QTRiNipBM
Generated by Claude Code