From 5001c037116386cb3f3316d5e4459fe78a4bd3fc Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 29 Aug 2025 17:14:27 +0300 Subject: [PATCH] Properly process files that cannot be open for a reason (#37170) Follow-up of https://github.com/zed-industries/zed/pull/36764 * Fix `anyhow!({e})` conversion lossing Collab error codes context when opening a buffer remotely * Use this context to only allow opening files that had not specific Collab error code Release Notes: - N/A --- crates/client/src/client.rs | 15 ++---------- crates/project/src/buffer_store.rs | 22 ++++++++++++++--- crates/remote/src/remote_client.rs | 2 +- crates/workspace/src/workspace.rs | 39 ++++++++++++++++++------------ 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index bdbf049b75ef1e0de351c65be7382a94d73448e6..1e735b0025f1e8a15809b096c5a462361d4ed8f3 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -1696,21 +1696,10 @@ impl Client { ); cx.spawn(async move |_| match future.await { Ok(()) => { - log::debug!( - "rpc message handled. client_id:{}, sender_id:{:?}, type:{}", - client_id, - original_sender_id, - type_name - ); + log::debug!("rpc message handled. client_id:{client_id}, sender_id:{original_sender_id:?}, type:{type_name}"); } Err(error) => { - log::error!( - "error handling message. client_id:{}, sender_id:{:?}, type:{}, error:{:?}", - client_id, - original_sender_id, - type_name, - error - ); + log::error!("error handling message. client_id:{client_id}, sender_id:{original_sender_id:?}, type:{type_name}, error:{error:#}"); } }) .detach(); diff --git a/crates/project/src/buffer_store.rs b/crates/project/src/buffer_store.rs index 295bad6e596252cbbeecb36b587b696ccbab32a0..89bd4b27c9c47470a781e0ff322f5ef4a29b4927 100644 --- a/crates/project/src/buffer_store.rs +++ b/crates/project/src/buffer_store.rs @@ -20,7 +20,7 @@ use language::{ }, }; use rpc::{ - AnyProtoClient, ErrorExt as _, TypedEnvelope, + AnyProtoClient, ErrorCode, ErrorExt as _, TypedEnvelope, proto::{self, ToProto}, }; use smol::channel::Receiver; @@ -837,7 +837,15 @@ impl BufferStore { } }; - cx.background_spawn(async move { task.await.map_err(|e| anyhow!("{e}")) }) + cx.background_spawn(async move { + task.await.map_err(|e| { + if e.error_code() != ErrorCode::Internal { + anyhow!(e.error_code()) + } else { + anyhow!("{e}") + } + }) + }) } pub fn create_buffer(&mut self, cx: &mut Context) -> Task>> { @@ -944,7 +952,15 @@ impl BufferStore { ) -> impl Iterator>>)> { self.loading_buffers.iter().map(|(path, task)| { let task = task.clone(); - (path, async move { task.await.map_err(|e| anyhow!("{e}")) }) + (path, async move { + task.await.map_err(|e| { + if e.error_code() != ErrorCode::Internal { + anyhow!(e.error_code()) + } else { + anyhow!("{e}") + } + }) + }) }) } diff --git a/crates/remote/src/remote_client.rs b/crates/remote/src/remote_client.rs index dd529ca87499b0daf2061fd990f7149828e3fce4..7e231e622cb2336a113799f7087fc0e30a5f79ff 100644 --- a/crates/remote/src/remote_client.rs +++ b/crates/remote/src/remote_client.rs @@ -1117,7 +1117,7 @@ impl ChannelClient { } Err(error) => { log::error!( - "{}:error handling message. type:{}, error:{}", + "{}:error handling message. type:{}, error:{:#}", this.name, type_name, format!("{error:#}").lines().fold( diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 0f119c14003d0f54f2f3a5323cb5e9106716a24d..61442eb6348e6152a4ad8ba4d3f93c24d1887346 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -648,23 +648,30 @@ impl ProjectItemRegistry { ) as Box<_>; Ok((project_entry_id, build_workspace_item)) } - Err(e) => match entry_abs_path.as_deref().filter(|_| is_file) { - Some(abs_path) => match cx.update(|window, cx| { - T::for_broken_project_item(abs_path, is_local, &e, window, cx) - })? { - Some(broken_project_item_view) => { - let build_workspace_item = Box::new( - move |_: &mut Pane, _: &mut Window, cx: &mut Context| { - cx.new(|_| broken_project_item_view).boxed_clone() - }, - ) - as Box<_>; - Ok((None, build_workspace_item)) + Err(e) => { + if e.error_code() == ErrorCode::Internal { + if let Some(abs_path) = + entry_abs_path.as_deref().filter(|_| is_file) + { + if let Some(broken_project_item_view) = + cx.update(|window, cx| { + T::for_broken_project_item( + abs_path, is_local, &e, window, cx, + ) + })? + { + let build_workspace_item = Box::new( + move |_: &mut Pane, _: &mut Window, cx: &mut Context| { + cx.new(|_| broken_project_item_view).boxed_clone() + }, + ) + as Box<_>; + return Ok((None, build_workspace_item)); + } } - None => Err(e)?, - }, - None => Err(e)?, - }, + } + Err(e) + } } })) });