eclipse-edc / eclipse-edc/Connector
Consumer discards the real termination reason/code received in an incoming TransferTerminationMessage
- Dominant language
- Java
- Stars
- 424
- Forks
- 300
- Avg merge
- 12h 19m
- Merged PRs (30d)
- 37
Description
**Component:** `org.eclipse.edc.connector.controlplane.services.transferprocess.TransferProcessProtocolServiceImpl`
**Version:** confirmed against `eclipse-edc` core `0.15.1` (as pinned by `tractusx-edc` `0.12.1`), via the actual compiled `edc-runtime.jar` — not source inspection alone.
### Summary
When a transfer is terminated because of a `DataFlow` failure, the provider correctly populates and sends the real failure reason over the wire — but the consumer's own connector silently discards it before persisting its local `TransferProcess`, so the consumer never has access to information the protocol already successfully delivered to it.
### What I found (via `javap -c -p` on the actual runtime jar)
1. On termination, `TransferProcessManagerImpl` builds the outgoing `TransferTerminationMessage` with `.reason(transferProcess.getErrorDetail())` — i.e. the real error string (e.g. an underlying `S3DataSourceException` message) is deliberately included.
2. `JsonObjectFromTransferTerminationMessageTransformer` serializes this `reason` (and `code`) onto the DSP wire message (`addIfNotNull`).
3. On the receiving side, `JsonObjectToTransferTerminationMessageTransformer` correctly parses `reason` back off the wire into the deserialized `TransferTerminationMessage` object.
4. But `TransferProcessProtocolServiceImpl.terminatedAction(TransferTerminationMessage, TransferProcess)` — the handler that actually processes this incoming message — never calls `message.getReason()` or `message.getCode()` at all. It only calls `transferProcess.transitionTerminatingRequested()` and `transferProcess.protocolMessageReceived(message.getId())` before saving. The parsed `reason` value is simply dropped.
I confirmed this live: the same failed transfer showed a populated `errorDetail` on the **provider's** `GET /v3/transferprocesses/{id}` response, and no `errorDetail` field at all on the **consumer's** response for the same transfer.
### Impact
In any real multi-organization dataspace, the consumer of a transfer has no access to the provider's logs or Management API. Today, when a transfer fails on the provider's side, the consumer's own connector receives the real reason over the wire and then throws it away — leaving the consumer with a bare `TERMINATED` state and no way to self-diagnose *why*, even though the information was already delivered to them.
### Suggested fix
`terminatedAction` (or wherever the consumer-side `TransferProcess` is updated from an incoming `TransferTerminationMessage`) should copy `message.getReason()` (and/or `getCode()`) onto the local `TransferProcess`'s `errorDetail`, the same field already used for locally-originated failures.
### Reproduction
1. Configure a push transfer (e.g. `AmazonS3-PUSH`) where the source object doesn't exist.
2. Start the transfer as consumer; it will progress to `STARTED` then `TERMINATED` once the provider's data-plane fails to read the source.
3. `GET /v3/transferprocesses/{id}` on the **provider** shows a populated `errorDetail`.
4. `GET /v3/transferprocesses/{id}` on the **consumer**, for the same transfer, shows no `errorDetail` at all.
Contributor guide
Research direction
Start in org.eclipse.edc.connector.controlplane.services.transferprocess.TransferProcessProtocolServiceImpl, focusing on terminatedAction and how the incoming TransferTerminationMessage updates the local TransferProcess. Review the message transformers to confirm reason and code are available, then reproduce the AmazonS3-PUSH failure and compare provider and consumer GET /v3/transferprocesses/{id} responses. Done means the consumer exposes the received termination detail.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100