98 lines
4.0 KiB
Markdown
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)
|