From 7d79146eb25b54d4567ddd2777576ac5c63baf3c Mon Sep 17 00:00:00 2001 From: "zed-zippy[bot]" <234243425+zed-zippy[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 08:51:28 +0000 Subject: [PATCH] thread_view: Add fallback error handling for connect failures (#50063) (cherry-pick to preview) (#50067) Cherry-pick of #50063 to preview ---- Following up from https://github.com/zed-industries/zed/pull/50061: when connecting to an ACP adapter fails before any thread is active, errors would not display in the Agent Panel. Falling back to `handle_load_error` to show the error UI properly as it already handles this. Before you mark this PR as ready for review, make sure that you have: - [x] Added a solid test coverage and/or screenshots from doing manual testing - [x] Done a self-review taking into account security and performance aspects - [x] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - Added fallback error handling for connect failures in the Agent Panel Co-authored-by: Kunall Banerjee --- crates/agent_ui/src/acp/thread_view.rs | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 41e0548efe4cf2191337e4d1c962b0a764bb2316..af06d33240cfbe49746bf3a228cd8cf10dc305b4 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -478,6 +478,8 @@ impl AcpServerView { this.handle_load_error(err, window, cx); } else if let Some(active) = this.active_thread() { active.update(cx, |active, cx| active.handle_any_thread_error(err, cx)); + } else { + this.handle_load_error(err, window, cx); } cx.notify(); }) @@ -2950,6 +2952,38 @@ pub(crate) mod tests { }); } + #[gpui::test] + async fn test_connect_failure_transitions_to_load_error(cx: &mut TestAppContext) { + init_test(cx); + + let (thread_view, cx) = setup_thread_view(FailingAgentServer, cx).await; + + thread_view.read_with(cx, |view, cx| { + let title = view.title(cx); + assert_eq!( + title.as_ref(), + "Error Loading Codex CLI", + "Tab title should show the agent name with an error prefix" + ); + match &view.server_state { + ServerState::LoadError(LoadError::Other(msg)) => { + assert!( + msg.contains("Invalid gzip header"), + "Error callout should contain the underlying extraction error, got: {msg}" + ); + } + other => panic!( + "Expected LoadError::Other, got: {}", + match other { + ServerState::Loading(_) => "Loading (stuck!)", + ServerState::LoadError(_) => "LoadError (wrong variant)", + ServerState::Connected(_) => "Connected", + } + ), + } + }); + } + #[gpui::test] async fn test_auth_required_on_initial_connect(cx: &mut TestAppContext) { init_test(cx); @@ -3460,6 +3494,36 @@ pub(crate) mod tests { } } + struct FailingAgentServer; + + impl AgentServer for FailingAgentServer { + fn logo(&self) -> ui::IconName { + ui::IconName::AiOpenAi + } + + fn name(&self) -> SharedString { + "Codex CLI".into() + } + + fn connect( + &self, + _root_dir: Option<&Path>, + _delegate: AgentServerDelegate, + _cx: &mut App, + ) -> Task, Option)>> { + Task::ready(Err(anyhow!( + "extracting downloaded asset for \ + https://github.com/zed-industries/codex-acp/releases/download/v0.9.4/\ + codex-acp-0.9.4-aarch64-pc-windows-msvc.zip: \ + failed to iterate over archive: Invalid gzip header" + ))) + } + + fn into_any(self: Rc) -> Rc { + self + } + } + #[derive(Clone)] struct StubSessionList { sessions: Vec,