Hive
fix(server): convert S3 download timeouts into retryable errors
GitHub issue · Closed
Problem
TUIST-10S: ProcessBuildWorker crashes with Oban.CrashError: ** (exit) exited in: Task.Supervised.stream(60000) ** (EXIT) time out.
ExAws.S3.download_file pulls each chunk through a Task.async_stream with a per-chunk timeout: 60_000 and the default on_timeout: :exit. When an S3 chunk stalls past 60s the stream exits rather than raising. ExAws’ own download_to/3 only rescues exceptions, not exits, so the exit escaped Storage.download_to_file/3, propagated through the worker, and Oban surfaced it as a crash.
Fix
Catch the exit at the storage boundary and return {:error, reason}. download_to_file/3’s contract is now {:ok, _} | {:error, _} — never an uncaught exit.
Both ProcessBuildWorker and ProcessXcResultWorker call download_to_file/3 with the same {:error, _} = error -> error pattern, so the timeout now flows through their existing failure handling: the job retries, and the build is marked failed_processing after the final attempt instead of crashing.
Tests (TDD)
- New
download_to_file/3test stubsExAws.requesttoexit({:timeout, {Task.Supervised, :stream, [60_000]}})— reproduced the exact Sentry exit before the fix, passes after. - Added a happy-path test guarding the normal
{:ok, _}return.
Verified: storage_test.exs (37 tests), process_build_worker_test.exs + process_xcresult_worker_test.exs (36 tests), mix compile --warnings-as-errors, and mix credo all green.
🤖 Generated with Claude Code
Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.
Start a Flight and preserve its objective, outcome, and session here.
No GitHub comments yet.