claw-code/docs/pr-3214-plan.md

98 lines
4.0 KiB
Markdown

# PR #3214 — Execution Plan: API Timeout/Retry
**Branch**: `worktree-api-timeout-retry-v2`
**Worktree**: `.claude/worktrees/api-timeout-retry-v2`
**CI State**: **Build ❌** Test ❌ Fmt ❌ Clippy ✅ Docs ✅ Windows ✅
## Reviewer Feedback
From `1716775457damn`:
> "Good revival of the stalled #2816. Retry-After header and 400 transient retry are particularly valuable for handling API rate limits. Are defaults preserved so existing behavior is unchanged?"
## Investigation Findings
### Root cause of all 3 CI failures: ONE missing field
**Build ❌**: `error[E0063]: missing field retry_after in initializer of ApiError` at `main.rs:11685`
A test constructs `ApiError::Api { ... }` but omits the new `retry_after` field. Same error blocks **Test ❌** (can't compile → can't run tests). **Fmt ❌** is separate (formatting issues).
Local build succeeds because local Rust may be a slightly different version, but CI uses stable with stricter defaults.
### Answering the reviewer's question
**"Are defaults preserved so existing behavior is unchanged?"** → **Yes, fully preserved.**
1. `ApiTimeoutConfig::default()``connect_timeout_secs: 30`, `request_timeout_secs: 300`, `max_retries: 8`
2. `CLAW_API_CONNECT_TIMEOUT` / `CLAW_API_REQUEST_TIMEOUT` env vars fall back to 30s/300s when unset
3. Both `AnthropicClient` and `OpenAiCompatClient` constructors use `DEFAULT_MAX_RETRIES` (8), `DEFAULT_INITIAL_BACKOFF` (1s), `DEFAULT_MAX_BACKOFF` (128s)
4. `with_retry_policy()` is **opt-in** — must be explicitly called to override defaults
5. The `retry_after` field on `ApiError::Api` defaults to `None` (no Retry-After header → no override of backoff)
No existing behavior changes unless the user explicitly configures new settings.
### Additional issue: duplicate `#[must_use]` attribute
`error.rs:134` and `error.rs:138` both have `#[must_use]` on the same `retry_after()` method. The compiler warns about this.
## Execution Plan
### Step 1: Fix missing `retry_after` field in main.rs test
Add `retry_after: None` to the `ApiError::Api` construction at line 11685.
**File**: `rust/crates/rusty-claude-cli/src/main.rs`
### Step 2: Fix duplicate `#[must_use]` attribute in error.rs
Remove the duplicate `#[must_use]` on line 138 of `error.rs`. Keep the one on line 134 (above the doc comment, which is the conventional placement).
**File**: `rust/crates/api/src/error.rs`
### Step 3: Run `cargo fmt --all`
Fix formatting.
### Step 4: Verify — cargo check, cargo test -p api, cargo test -p rusty-claude-cli
Ensure building and testing passes.
## Commit Details
**Commit**: `76783377` on `worktree-api-timeout-retry-v2`
```
fix: address CI failures and reviewer feedback on #3214
- Add missing retry_after: None field to ApiError::Api construction
in main.rs test. This field was introduced by the Retry-After
header support but was not added to the test's error initializer,
causing a compile error under CI's strict mode.
- Remove duplicate #[must_use] attribute on retry_after() method
in error.rs (lines 134+138 both had it; kept the outer one
above the doc comment per convention).
- Cargo fmt --all run.
- Reviewer question "Are defaults preserved?" — answered yes:
ApiTimeoutConfig defaults to 30s connect / 300s request / 8 retries.
with_retry_policy() is opt-in. No behavior change without explicit
configuration.
```
**Files changed**:
- `rust/crates/api/src/error.rs` — removed duplicate `#[must_use]` on line 138
- `rust/crates/rusty-claude-cli/src/main.rs` — added `retry_after: None` to test + fmt fix
## Acceptance Criteria
- [x] `retry_after: None` added to `ApiError::Api` test construction at main.rs:11685
- [x] Duplicate `#[must_use]` removed from `error.rs`
- [x] `cargo fmt --all` run
- [x] `cargo build -p api` passes
- [x] `cargo build -p rusty-claude-cli` passes
- [x] `cargo test -p api` passes (147 unit + 37 integration)
- [x] Changes committed and pushed (commit `76783377`)
- [x] Reviewer question answered: defaults preserved (30s/300s/8, opt-in)