fix(tower-runtime): preserve error details in SpawnFailed and PackageUnpackFailed#285
fix(tower-runtime): preserve error details in SpawnFailed and PackageUnpackFailed#285sammuti wants to merge 1 commit into
Conversation
…UnpackFailed Previously, `From<tower_uv::Error>` and `From<std::io::Error>` conversions discarded the inner error message, making `SpawnFailed` and `PackageUnpackFailed` uninformative in logs and traces. The termination log and trace spans would just show "SpawnFailed" with no context about whether uv was missing, a permission was denied, pyproject.toml was absent, etc. Add a `detail: String` field to both variants and propagate the original error message through the conversion. Also add `Display` impl for `tower_uv::Error` so it can be stringified cleanly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
This PR is targeting If this is a regular feature/fix PR, please change the base branch to Current base: |
📝 WalkthroughWalkthroughError variants ChangesError Detail Enrichment
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
This PR is targeting If this is a regular feature/fix PR, please change the base branch to Current base: |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/tower-runtime/src/errors.rs (1)
82-85: ⚡ Quick winStandardize I/O detail formatting in spawn conversion.
Line 84 currently uses raw
err.to_string(), so this path omits theIO error:prefix used bytower_uv::Error::IoError. Prefixing here keepsSpawnFailedmessages consistent across conversion paths.Suggested patch
impl From<std::io::Error> for Error { fn from(err: std::io::Error) -> Self { Error::SpawnFailed { - detail: err.to_string(), + detail: format!("IO error: {err}"), } } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/tower-runtime/src/errors.rs` around lines 82 - 85, The SpawnFailed conversion currently uses err.to_string() directly; change the conversion in the From<std::io::Error> implementation so the detail string is prefixed with "IO error: " (e.g., build the detail as format!("IO error: {}", err)) to match the formatting used by tower_uv::Error::IoError and keep Error::SpawnFailed messages consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@crates/tower-runtime/src/errors.rs`:
- Around line 82-85: The SpawnFailed conversion currently uses err.to_string()
directly; change the conversion in the From<std::io::Error> implementation so
the detail string is prefixed with "IO error: " (e.g., build the detail as
format!("IO error: {}", err)) to match the formatting used by
tower_uv::Error::IoError and keep Error::SpawnFailed messages consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 2fdfb143-4d30-4bf4-bda0-8a3665bba3ae
📒 Files selected for processing (3)
crates/tower-runtime/src/errors.rscrates/tower-runtime/src/subprocess.rscrates/tower-uv/src/lib.rs
bradhe
left a comment
There was a problem hiding this comment.
Looks good. Just fix failing CI.
Summary
detail: Stringfield toError::SpawnFailedandError::PackageUnpackFailedso the root cause (IO error, missing uv, permission denied, etc.) flows through to termination logs and trace spansDisplayimpl fortower_uv::Errortower_uv::Errorvariants were mapped to a bareError::SpawnFailedwith no context, making productionspawn_failederrors impossible to diagnose without pod-level accessContext
Investigating TOW-2151/TOW-2160 (WaiterClosed) and recent
spawn_failederrors on May 31, we found that while the structuredAppCompletion::Failedpipeline (from #274) correctly surfaces the error kind, the actual error message was always just "SpawnFailed" because theFrom<tower_uv::Error>impl discarded the inner detail.After this change, termination logs and trace spans will show messages like:
spawning process: not found: uv binary not found in PATHspawning process: IO error: No such file or directory (os error 2)spawning process: permission denied: /app/.venv/bin/pythonpackage unpack failed: InvalidManifestTest plan
cargo check --workspacepassescargo test --workspacepasses🤖 Generated with Claude Code
Summary by CodeRabbit