recent_projects: Surface project opening errors to user (#41308)

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth
2025-10-28 06:44:44 +00:00
committed by GitHub
parent 73bd12ebbe
commit 46c5d515bf
3 changed files with 77 additions and 75 deletions
+70 -67
View File
@@ -28,7 +28,8 @@ use ui::{KeyBinding, ListItem, ListItemSpacing, Tooltip, prelude::*, tooltip_con
use util::{ResultExt, paths::PathExt};
use workspace::{
CloseIntent, HistoryManager, ModalView, OpenOptions, PathList, SerializedWorkspaceLocation,
WORKSPACE_DB, Workspace, WorkspaceId, with_active_or_new_workspace,
WORKSPACE_DB, Workspace, WorkspaceId, notifications::DetachAndPromptErr,
with_active_or_new_workspace,
};
use zed_actions::{OpenRecent, OpenRemote};
@@ -420,77 +421,79 @@ impl PickerDelegate for RecentProjectsDelegate {
} else {
!secondary
};
workspace
.update(cx, |workspace, cx| {
if workspace.database_id() == Some(*candidate_workspace_id) {
Task::ready(Ok(()))
} else {
match candidate_workspace_location.clone() {
SerializedWorkspaceLocation::Local => {
let paths = candidate_workspace_paths.paths().to_vec();
if replace_current_window {
cx.spawn_in(window, async move |workspace, cx| {
let continue_replacing = workspace
.update_in(cx, |workspace, window, cx| {
workspace.prepare_to_close(
CloseIntent::ReplaceWindow,
window,
cx,
)
})?
.await?;
if continue_replacing {
workspace.update(cx, |workspace, cx| {
if workspace.database_id() == Some(*candidate_workspace_id) {
return;
}
match candidate_workspace_location.clone() {
SerializedWorkspaceLocation::Local => {
let paths = candidate_workspace_paths.paths().to_vec();
if replace_current_window {
cx.spawn_in(window, async move |workspace, cx| {
let continue_replacing = workspace
.update_in(cx, |workspace, window, cx| {
workspace.prepare_to_close(
CloseIntent::ReplaceWindow,
window,
cx,
)
})?
.await?;
if continue_replacing {
workspace
.update_in(cx, |workspace, window, cx| {
workspace
.update_in(cx, |workspace, window, cx| {
workspace.open_workspace_for_paths(
true, paths, window, cx,
)
})?
.await
} else {
Ok(())
}
})
.open_workspace_for_paths(true, paths, window, cx)
})?
.await
} else {
workspace.open_workspace_for_paths(false, paths, window, cx)
Ok(())
}
}
SerializedWorkspaceLocation::Remote(mut connection) => {
let app_state = workspace.app_state().clone();
let replace_window = if replace_current_window {
window.window_handle().downcast::<Workspace>()
} else {
None
};
let open_options = OpenOptions {
replace_window,
..Default::default()
};
if let RemoteConnectionOptions::Ssh(connection) = &mut connection {
SshSettings::get_global(cx)
.fill_connection_options_from_settings(connection);
};
let paths = candidate_workspace_paths.paths().to_vec();
cx.spawn_in(window, async move |_, cx| {
open_remote_project(
connection.clone(),
paths,
app_state,
open_options,
cx,
)
.await
})
}
})
} else {
workspace.open_workspace_for_paths(false, paths, window, cx)
}
}
})
.detach_and_log_err(cx);
SerializedWorkspaceLocation::Remote(mut connection) => {
let app_state = workspace.app_state().clone();
let replace_window = if replace_current_window {
window.window_handle().downcast::<Workspace>()
} else {
None
};
let open_options = OpenOptions {
replace_window,
..Default::default()
};
if let RemoteConnectionOptions::Ssh(connection) = &mut connection {
SshSettings::get_global(cx)
.fill_connection_options_from_settings(connection);
};
let paths = candidate_workspace_paths.paths().to_vec();
cx.spawn_in(window, async move |_, cx| {
open_remote_project(
connection.clone(),
paths,
app_state,
open_options,
cx,
)
.await
})
}
}
.detach_and_prompt_err(
"Failed to open project",
window,
cx,
|_, _, _| None,
);
});
cx.emit(DismissEvent);
}
}
@@ -483,7 +483,7 @@ impl remote::RemoteClientDelegate for RemoteClientDelegate {
cx: &mut AsyncApp,
) -> Task<anyhow::Result<PathBuf>> {
cx.spawn(async move |cx| {
let binary_path = AutoUpdater::download_remote_server_release(
AutoUpdater::download_remote_server_release(
platform.os,
platform.arch,
release_channel,
@@ -500,8 +500,7 @@ impl remote::RemoteClientDelegate for RemoteClientDelegate {
platform.os,
platform.arch,
)
})?;
Ok(binary_path)
})
})
}
+5 -5
View File
@@ -528,6 +528,7 @@ impl RemoteClient {
let reconnect_task = cx.spawn(async move |this, cx| {
macro_rules! failed {
($error:expr, $attempts:expr, $ssh_connection:expr, $delegate:expr) => {
delegate.set_status(Some(&format!("{error:#}", error = $error)), cx);
return State::ReconnectFailed {
error: anyhow!($error),
attempts: $attempts,
@@ -999,11 +1000,10 @@ impl ConnectionPool {
let connection = self.connections.get(&opts);
match connection {
Some(ConnectionPoolEntry::Connecting(task)) => {
let delegate = delegate.clone();
cx.spawn(async move |cx| {
delegate.set_status(Some("Waiting for existing connection attempt"), cx);
})
.detach();
delegate.set_status(
Some("Waiting for existing connection attempt"),
&mut cx.to_async(),
);
return task.clone();
}
Some(ConnectionPoolEntry::Connected(ssh)) => {