Repository navigation
feat(a2a): adopt the standard A2A error envelope - #46
Merged
Zhoujie628 merged 4 commits intoSep 4, 2026
Merged
Conversation
Detect the google.rpc.Status error envelope on direct responses and SSE
data, projecting httpStatus, code, status, reason, domain, typed details
and Retry-After into stable workflow error codes (a2a.<reason>, with an
a2a.http.<status> fallback when no reason is observed).
Remove the legacy {status,title,detail} problem compatibility
(RemoteProblemException, ProblemDetectingHttpClient) per the agreement
that OMC returns the standard envelope for pre-task-creation failures.
Fail immediately when an SSE stream completes without delivering any
event instead of waiting out the send timeout; the observed HTTP status
is not fabricated when the transport cannot expose it. Stop logging
subscriber-initiated cancellations as transport failures and redact
failure messages in protocol logs.
Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
A wildcard ResponseEntity<?> return bypassed Spring's emitter handler, so every message:stream and task subscription response degraded to an HTTP 500 with an empty body; the client-side SDK then treated the zero-event completion as success and callers waited out the send timeout. Declare SseEmitter as the return type and throw A2AError for pre-stream failures, mapped by an @ExceptionHandler to a non-2xx application/a2a+json standard envelope. Enforce the SDK pre-contracts in order (streaming capability, protocol version, required extensions, task access) before dispatch. Release the Flow subscription and notify the SDK event consumer on completion, error, timeout and write failure. Declare text/event-stream produces on the streaming mappings and return application/a2a+json on protocol responses. The negative tests now go through MockMvc dispatch, which is what would have caught the 500 regression. Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
MainEventBusProcessor.ensureStarted() is an intentional CDI no-op, so manual wiring must start the processor thread explicitly; the previous replacement of the reflective start left the bus dead and every inbound task hung. Start the thread in start(), interrupt and join it in close(), create the SSL context before binding the listen address, and unify the two SSE endpoints' write and cleanup paths including the SDK event-consumer cancel callback. Extend the failure E2E to assert that standard 400/429 envelopes reach the northbound failure with stable error codes and no negotiation or merge dispatch. Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
Split pre-task-creation failures (non-2xx HTTP plus the google.rpc.Status envelope) from post-creation task failures (HTTP 200 with TASK_STATE_FAILED carrying business evidence). Document the zero-event fast-fail, the rule against fabricating HTTP statuses the transport cannot observe, the six server endpoints with their media types, and the stream cleanup semantics. Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
Zhoujie628
added a commit
to Zhoujie628/workflow-engine-sdk-java
that referenced
this pull request
Sep 4, 2026
Bring dev up to the merged main baseline (error-envelope PR project-openan#46 and the module-view docs PR project-openan#44) while preserving the Eastcom Order overlay. Resolution policy: workflow-engine and spring-boot-starter take main verbatim; samples and root files keep main's newer common content plus dev's Eastcom additions (gateway runtime factory, order transport mode, mock gateway, Eastcom CI gate and docs); parallel-evolved tests take main's canonical versions. Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
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 #45
Summary
Aligns the engine with the A2A specification's error handling (pre-task failures as non-2xx +
google.rpc.Statusenvelope; post-creation failures stay HTTP 200 +TASK_STATE_FAILED):a2a.<reason>,a2a.http.<status>fallback) with full errorDetails (httpStatus/code/status/reason/domain/details/Retry-After). Legacy{status,title,detail}compatibility removed. SSE streams that complete without any event now fail immediately instead of waiting out the send timeout; no fabricated HTTP statuses.SseEmitterdirectly; pre-stream failures throwA2AError, mapped by@ExceptionHandlerto a non-2xxapplication/a2a+jsonenvelope. A wildcardResponseEntity<?>return previously bypassed Spring's emitter handler and degraded every streaming response to HTTP 500. SDK pre-contracts (streaming capability, protocol version, required extensions, task access) enforced in SDK order; stream cleanup releases the Flow subscription and notifies the SDK event consumer.ensureStarted()is an intentional CDI no-op — manual wiring previously left the bus dead and tasks hung); SSL context created before binding; unified SSE write/cleanup paths.Test plan
mvn test: 292/292 (engine 192, starter 10, samples 90)a2a.invalid_params, 429 ->a2a.active_task_limit_exceeded; northbound receivesTASK_STATE_FAILEDwith errorDetails; no negotiation, no re-submission, merge step skippedgit diff --checkclean🤖 Generated with Claude Code