Skip to content

improve multipart part retries with exponential backoff & preserve root errors - #44

Merged
patricioxavier8 merged 2 commits into
mainfrom
fix/multipart-retry-backoff
Jul 22, 2026
Merged

patricioxavier8 merged 2 commits into
mainfrom
fix/multipart-retry-backoff

Conversation

@patricioxavier8

Copy link
Copy Markdown
Contributor

📌 Summary

Fixes an issue where multipart upload failures were masked as UploadNotSuccessful due to unhandled abort states in NetworkFacade.
Previously, part-level retries were only triggered during offline states (notConnectedToInternet / networkConnectionLost), while transient network issues like S3 request timeouts (-1001), server errors (5xx), or rate limits (429) failed immediately without retrying.
This PR improves part-level resilience by introducing Exponential Backoff with Jitter, selective error classification for transient failures, preserving underlying root-cause errors, conforming UploadError to LocalizedError.

🛠️ Changes Introduced

  • Smart Part-Level Retry & Error Classification:

    • Previous Behavior: Part retries only handled complete internet disconnection (notConnectedToInternet / networkConnectionLost) and retried immediately without delay.
    • New Behavior: Added isRetryableChunkError to retry transient network conditions (timeouts -1001, host unreachable -1003/-1004, HTTP 5xx, HTTP 429, HTTP status -1) while immediately aborting non-retryable errors (e.g. HTTP 4xx).
  • Exponential Backoff & Jitter:

    • Implemented exponential delay calculation (pow(2.0, attempt)) with random jitter in UploadPartOperation.uploadPartWithRetry() to prevent request storms against S3 endpoints during transient hiccups.
  • Error Preservation & Propagation:

    • Updated uploadState.setAborted(error: partError) and encryptFileIntoChunks in NetworkFacade.swift to preserve and propagate the actual PartUploadFailed error instead of falling back to generic UploadError.UploadNotSuccessful.
  • HTTP Status Code Exposure & Localized Errors:

    • Modified UploadMultipart.swift to return non-200 S3 responses wrapped in PartUploadFailed containing the actual HTTP status code.
    • Conformed UploadError to LocalizedError for descriptive string representations in system logs (PartUploadFailed(partIndex: X, error: Y)).

… upload errors

- Fix abort state in NetworkFacade to preserve and propagate actual abort errors instead of masking them as UploadNotSuccessful.
- Implement exponential backoff with jitter and selective error filtering (isRetryableChunkError) in UploadPartOperation.
- Pass HTTP status code in PartUploadFailed for non-200 S3 responses in UploadMultipart.
- Conform UploadError to LocalizedError for clean string descriptions.
@patricioxavier8
patricioxavier8 requested a review from sg-gs July 22, 2026 04:38
Comment thread Tests/InternxtSwiftCoreTests/Services/Network/NetworkFacadeTests.swift Outdated
@patricioxavier8
patricioxavier8 requested a review from sg-gs July 22, 2026 14:26
@patricioxavier8
patricioxavier8 merged commit ad2ca2c into main Jul 22, 2026
1 check passed
@patricioxavier8
patricioxavier8 deleted the fix/multipart-retry-backoff branch July 22, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants