codex: address PR review feedback (#18290)

This commit is contained in:
Eric Traut
2026-04-17 00:07:55 -07:00
parent 5588ecfec5
commit 6ff6061177
2 changed files with 78 additions and 15 deletions

View File

@@ -6301,6 +6301,8 @@ impl ChatWidget {
notification.error.additional_details,
);
}
} else if from_replay {
self.last_non_retry_error = None;
} else {
self.last_non_retry_error = Some((
notification.turn_id.clone(),
@@ -6498,6 +6500,10 @@ impl ChatWidget {
self.on_interrupted_turn(TurnAbortReason::Interrupted);
}
TurnStatus::Failed => {
if replay_kind.is_some() {
self.last_non_retry_error = None;
return;
}
if let Some(error) = notification.turn.error {
if self.last_non_retry_error.as_ref()
== Some(&(notification.turn.id.clone(), error.message.clone()))
@@ -6835,24 +6841,26 @@ impl ChatWidget {
message,
codex_error_info,
}) => {
if codex_error_info
.as_ref()
.is_some_and(|info| self.handle_steer_rejected_error(info))
if !from_replay
&& !codex_error_info
.as_ref()
.is_some_and(|info| self.handle_steer_rejected_error(info))
{
} else if let Some(kind) = codex_error_info
.as_ref()
.and_then(core_rate_limit_error_kind)
{
match kind {
RateLimitErrorKind::ServerOverloaded => {
self.on_server_overloaded_error(message)
}
RateLimitErrorKind::UsageLimit | RateLimitErrorKind::Generic => {
self.on_error(message)
if let Some(kind) = codex_error_info
.as_ref()
.and_then(core_rate_limit_error_kind)
{
match kind {
RateLimitErrorKind::ServerOverloaded => {
self.on_server_overloaded_error(message)
}
RateLimitErrorKind::UsageLimit | RateLimitErrorKind::Generic => {
self.on_error(message)
}
}
} else {
self.on_error(message);
}
} else {
self.on_error(message);
}
}
EventMsg::McpStartupUpdate(ev) => self.on_mcp_startup_update(ev),

View File

@@ -898,6 +898,61 @@ async fn replayed_buffered_shell_turn_completion_clears_pending_shell_marker() {
assert!(!chat.pending_standalone_user_shell_command);
}
#[tokio::test]
async fn replayed_non_retry_error_preserves_pending_shell_submit_markers() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
chat.pending_turn_start_after_submit = true;
chat.pending_standalone_user_shell_command = true;
chat.handle_server_notification(
ServerNotification::Error(ErrorNotification {
error: AppServerTurnError {
message: "permission denied".to_string(),
codex_error_info: None,
additional_details: None,
},
will_retry: false,
thread_id: "thread-1".to_string(),
turn_id: "old-turn".to_string(),
}),
Some(ReplayKind::ThreadSnapshot),
);
assert!(drain_insert_history(&mut rx).is_empty());
assert!(chat.pending_turn_start_after_submit);
assert!(chat.pending_standalone_user_shell_command);
assert!(chat.standalone_user_shell_turn_id.is_none());
}
#[tokio::test]
async fn replayed_failed_completed_turn_preserves_pending_shell_submit_markers() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
chat.pending_turn_start_after_submit = true;
chat.pending_standalone_user_shell_command = true;
chat.replay_thread_turns(
vec![AppServerTurn {
id: "old-turn".to_string(),
items: Vec::new(),
status: AppServerTurnStatus::Failed,
error: Some(AppServerTurnError {
message: "permission denied".to_string(),
codex_error_info: None,
additional_details: None,
}),
started_at: None,
completed_at: Some(0),
duration_ms: None,
}],
ReplayKind::ThreadSnapshot,
);
assert!(drain_insert_history(&mut rx).is_empty());
assert!(chat.pending_turn_start_after_submit);
assert!(chat.pending_standalone_user_shell_command);
assert!(chat.standalone_user_shell_turn_id.is_none());
}
#[tokio::test]
async fn replayed_stream_error_does_not_set_retry_status_or_status_indicator() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;