Files
codex/codex-rs/tui/src/app/agents_overview_errors.rs
T
Eric Traut 07757f448f Explain session creation failures during server shutdown (#52721)
## Why

Graceful shutdown rejects new sessions with an invalid-request error. Give clients a structured shutdown reason and show command center users why session creation is paused.

## What changed

- Add `data: {"reason":"serverShuttingDown"}` to app-server shutdown admission errors while retaining JSON-RPC code `-32600`.
- Show a dedicated shutdown message explaining the wait for active turns and automatic reconnection for non-embedded servers. Recognize older servers by their exact draining message only when error data is absent, and preserve retained-worktree cleanup guidance.
- Keep the command center reconnect presentation when a shutdown error covers the initial overview and no conversation is open.

## Testing

Extend admission and WebSocket shutdown assertions, add embedded and daemon shutdown message snapshots, and cover reconnection with a shutdown error over the initial command center.

GitOrigin-RevId: f167144c0ddc77872afdf3daac8bb1c89f3425b4
2026-10-09 23:16:46 +00:00

58 lines
1.8 KiB
Rust

//! Reports command-center action failures above the retained dashboard.
use super::*;
use crate::wrapping::word_wrap_lines;
use ratatui::buffer::Buffer;
struct AgentsOverviewErrorHeader(Vec<Line<'static>>);
impl Renderable for AgentsOverviewErrorHeader {
fn render(&self, area: Rect, buf: &mut Buffer) {
Renderable::render(
&Paragraph::new(word_wrap_lines(&self.0, usize::from(area.width))),
area,
buf,
);
}
fn desired_height(&self, width: u16) -> u16 {
word_wrap_lines(&self.0, usize::from(width)).len() as u16
}
}
impl App {
pub(in crate::app) fn add_agents_overview_error(&mut self, message: String) {
self.show_agents_overview_error(/*title*/ None, message);
}
pub(in crate::app) fn show_agents_overview_error(
&mut self,
title: Option<&'static str>,
message: String,
) {
if self
.chat_widget
.selected_index_for_present_view(AGENTS_OVERVIEW_VIEW_ID)
.is_some()
{
let items = vec![SelectionItem {
name: "Return to command center".to_string(),
dismiss_on_select: true,
..Default::default()
}];
self.chat_widget.show_selection_view(SelectionViewParams {
header: Box::new(AgentsOverviewErrorHeader(vec![
Line::from(title.unwrap_or("Unable to complete action").bold()),
Line::from(message.clone().dim()),
])),
items,
..SelectionViewParams::picker()
});
}
self.chat_widget.add_error_message(match title {
Some(title) => format!("{title}: {message}"),
None => message,
});
}
}