mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-08 00:54:49 +08:00
Preserve recovery guidance for retried context-window failures
The CLI already reframes direct preflight and provider oversized-request errors, but retry-wrapped provider failures still fell back to the generic retry-exhausted surface because the user-visible formatter keyed off the safe failure class. Route formatting through nested context-window detection so wrapped provider failures keep the same compact/reduce-scope guidance. Constraint: Keep the fix UX-scoped without widening broader failure classification behavior Rejected: Reorder safe_failure_class for all RetriesExhausted errors | broader semantic change than needed for this issue Confidence: high Scope-risk: narrow Directive: Keep context-window rendering keyed to nested error inspection so provider wrappers do not lose recovery guidance Tested: cargo fmt --check; cargo test -p rusty-claude-cli context_window; cargo test -p api oversized Not-tested: Full workspace test suite
This commit is contained in:
@@ -5742,7 +5742,7 @@ impl ApiClient for AnthropicRuntimeClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn format_user_visible_api_error(session_id: &str, error: &api::ApiError) -> String {
|
fn format_user_visible_api_error(session_id: &str, error: &api::ApiError) -> String {
|
||||||
if error.safe_failure_class() == "context_window" {
|
if error.is_context_window_failure() {
|
||||||
format_context_window_blocked_error(session_id, error)
|
format_context_window_blocked_error(session_id, error)
|
||||||
} else if error.is_generic_fatal_wrapper() {
|
} else if error.is_generic_fatal_wrapper() {
|
||||||
let mut qualifiers = vec![format!("session {session_id}")];
|
let mut qualifiers = vec![format!("session {session_id}")];
|
||||||
@@ -6986,6 +6986,39 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn retry_wrapped_context_window_errors_keep_recovery_guidance() {
|
||||||
|
let error = ApiError::RetriesExhausted {
|
||||||
|
attempts: 2,
|
||||||
|
last_error: Box::new(ApiError::Api {
|
||||||
|
status: "413".parse().expect("status"),
|
||||||
|
error_type: Some("invalid_request_error".to_string()),
|
||||||
|
message: Some("Request is too large for this model's context window.".to_string()),
|
||||||
|
request_id: Some("req_ctx_retry_789".to_string()),
|
||||||
|
body: String::new(),
|
||||||
|
retryable: false,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
let rendered = format_user_visible_api_error("session-issue-32", &error);
|
||||||
|
assert!(rendered.contains("Context window blocked"), "{rendered}");
|
||||||
|
assert!(rendered.contains("context_window_blocked"), "{rendered}");
|
||||||
|
assert!(
|
||||||
|
rendered.contains("Trace req_ctx_retry_789"),
|
||||||
|
"{rendered}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
rendered
|
||||||
|
.contains("Detail Request is too large for this model's context window."),
|
||||||
|
"{rendered}"
|
||||||
|
);
|
||||||
|
assert!(rendered.contains("Compact /compact"), "{rendered}");
|
||||||
|
assert!(
|
||||||
|
rendered.contains("Resume compact claw --resume session-issue-32 /compact"),
|
||||||
|
"{rendered}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn temp_dir() -> PathBuf {
|
fn temp_dir() -> PathBuf {
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user