Skip to content

Retry surfaces the typed error, not a SuppressedError wrapper #72

Description

@Wahbeh-Mohammad

Part of the audit remediation umbrella #67. Milestone 3. Severity: HIGH. Requirements: XCUT-1, RETRY error contract.

Current SDK behavior

When retry gives up and the attempt trail is not empty, withTrail
(packages/core/src/retry/engine.ts:260-271) wraps the final error:
suppress(outcome.error, folded, 'retry attempts exhausted'). The surfaced object is a
SuppressedError. The typed error is at .error. The surfaced type therefore depends on how
many attempts ran:

Scenario Surfaced error
maxAttempts: 1, transport failure TransportFailureError
maxAttempts: 3 (default), same failure SuppressedError
abort during backoff, maxAttempts: 5 SuppressedError; instanceof CancellationError is false

The third row is the case the comment at :378-383 says abortToSdkError exists to fix. The
mapping is applied at :385 and undone by withTrail at :386. A backoff cancellation always
has a non-empty trail. XCUT-1's conformance clause is "assert the surfaced error is the
cancellation type". docs/sdk-documentation/write-a-response-handler.md:75-76 documents the
wrapper only for the RECOV-12 release-failure path.

Expected behavior

The error that retryStep and dispatchWithRetry surface is the typed error of the final
attempt. instanceof on that error gives the same result for one attempt and for many. A
cancellation during backoff surfaces CancellationError. The earlier attempts' errors remain
reachable from the surfaced error.

Notes and leads

  • Keep the final error primary. Attach the trail without changing the object's class: a
    cause chain, an errors array property (the AggregateError shape), or a documented
    attempts property on the typed leaf. If a dedicated RetryExhaustedError is wanted, it must
    still not hide CancellationError.
  • suppress() (packages/core/src/suppress.ts) is the right tool for release failures, not for
    attempt history.
  • Update write-a-response-handler.md and the retryStep TSDoc.
  • Tests: instanceof TransportFailureError for maxAttempts 1 and 3; instanceof CancellationError on abort during backoff; the trail is reachable. Add a row to
    tests/conformance/xcut/retry-safety.conformance.test.ts and
    cancellation-and-timeout.conformance.test.ts.
  • Behavior change: minor changeset for @dexpace/core. Record the trail shape in the Phase 5a
    ledger section.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions