diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 368c911cf0..7b8a4dfe87 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -6,7 +6,7 @@ use crate::{ persistence, }; use crate::{new_session_modal::NewSessionModal, session::DebugSession}; -use anyhow::{Result, anyhow}; +use anyhow::{Context as _, Result, anyhow}; use collections::{HashMap, HashSet}; use command_palette_hooks::CommandPaletteFilter; use dap::DebugRequest; @@ -500,7 +500,7 @@ impl DebugPanel { workspace.spawn_in_terminal(task.resolved.clone(), window, cx) })?; - let exit_status = run_build.await?; + let exit_status = run_build.await.transpose()?.context("task cancelled")?; if !exit_status.success() { anyhow::bail!("Build failed"); } diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 0ed8cc1acb..b905eea50d 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -46,7 +46,7 @@ use smol::channel::{Receiver, Sender}; use task::{HideStrategy, Shell, TaskId}; use terminal_settings::{AlternateScroll, CursorShape, TerminalSettings}; use theme::{ActiveTheme, Theme}; -use util::{ResultExt, paths::home_dir, truncate_and_trailoff}; +use util::{paths::home_dir, truncate_and_trailoff}; use std::{ cmp::{self, min}, @@ -1851,8 +1851,7 @@ impl Terminal { if let Some(task) = self.task() { if task.status == TaskStatus::Running { let completion_receiver = task.completion_rx.clone(); - return cx - .spawn(async move |_| completion_receiver.recv().await.log_err().flatten()); + return cx.spawn(async move |_| completion_receiver.recv().await.ok().flatten()); } else if let Ok(status) = task.completion_rx.try_recv() { return Task::ready(status); } diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index ad2a55e705..e2675fb11c 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -483,7 +483,7 @@ impl TerminalPanel { task: &SpawnInTerminal, window: &mut Window, cx: &mut Context, - ) -> Task>> { + ) -> Task>> { let Ok(is_local) = self .workspace .update(cx, |workspace, cx| workspace.project().read(cx).is_local()) @@ -552,12 +552,12 @@ impl TerminalPanel { cx.spawn(async move |_, _| rx.await?) } - pub fn spawn_in_new_terminal( + fn spawn_in_new_terminal( &mut self, spawn_task: SpawnInTerminal, window: &mut Window, cx: &mut Context, - ) -> Task>> { + ) -> Task>> { let reveal = spawn_task.reveal; let reveal_target = spawn_task.reveal_target; let kind = TerminalKind::Task(spawn_task); @@ -652,7 +652,7 @@ impl TerminalPanel { kind: TerminalKind, window: &mut Window, cx: &mut Context, - ) -> Task>> { + ) -> Task>> { if !is_enabled_in_workspace(workspace, cx) { return Task::ready(Err(anyhow!( "terminal not yet supported for remote projects" @@ -680,7 +680,7 @@ impl TerminalPanel { }); workspace.add_item_to_active_pane(Box::new(terminal_view), None, true, window, cx); })?; - Ok(terminal) + Ok(terminal.downgrade()) }) } @@ -690,7 +690,7 @@ impl TerminalPanel { reveal_strategy: RevealStrategy, window: &mut Window, cx: &mut Context, - ) -> Task>> { + ) -> Task>> { let workspace = self.workspace.clone(); cx.spawn_in(window, async move |terminal_panel, cx| { if workspace.update(cx, |workspace, cx| !is_enabled_in_workspace(workspace, cx))? { @@ -735,11 +735,12 @@ impl TerminalPanel { pane.add_item(terminal_view, true, focus, None, window, cx); }); - Ok(terminal) + Ok(terminal.downgrade()) })?; - terminal_panel.update(cx, |this, cx| { - this.pending_terminals_to_add = this.pending_terminals_to_add.saturating_sub(1); - this.serialize(cx) + terminal_panel.update(cx, |terminal_panel, cx| { + terminal_panel.pending_terminals_to_add = + terminal_panel.pending_terminals_to_add.saturating_sub(1); + terminal_panel.serialize(cx) })?; result }) @@ -802,7 +803,7 @@ impl TerminalPanel { terminal_to_replace: Entity, window: &mut Window, cx: &mut Context, - ) -> Task>> { + ) -> Task>> { let reveal = spawn_task.reveal; let reveal_target = spawn_task.reveal_target; let window_handle = window.window_handle(); @@ -884,7 +885,7 @@ impl TerminalPanel { RevealStrategy::Never => {} } - Ok(new_terminal) + Ok(new_terminal.downgrade()) }) } @@ -1458,22 +1459,25 @@ impl workspace::TerminalProvider for TerminalProvider { task: SpawnInTerminal, window: &mut Window, cx: &mut App, - ) -> Task> { - let this = self.0.clone(); + ) -> Task>> { + let terminal_panel = self.0.clone(); window.spawn(cx, async move |cx| { - let terminal = this + let terminal = terminal_panel .update_in(cx, |terminal_panel, window, cx| { terminal_panel.spawn_task(&task, window, cx) - })? - .await?; - let Some(exit_code) = terminal - .read_with(cx, |terminal, cx| terminal.wait_for_completed_task(cx))? - .await - else { - return Err(anyhow!("Task cancelled")); - }; - - Ok(exit_code) + }) + .ok()? + .await; + match terminal { + Ok(terminal) => { + let exit_status = terminal + .read_with(cx, |terminal, cx| terminal.wait_for_completed_task(cx)) + .ok()? + .await?; + Some(Ok(exit_status)) + } + Err(e) => Some(Err(e)), + } }) } } diff --git a/crates/vim/src/command.rs b/crates/vim/src/command.rs index 3645993eda..736d024fd0 100644 --- a/crates/vim/src/command.rs +++ b/crates/vim/src/command.rs @@ -1466,9 +1466,22 @@ impl ShellExec { show_command: false, show_rerun: false, }; - workspace - .spawn_in_terminal(spawn_in_terminal, window, cx) - .detach_and_log_err(cx); + + let task_status = workspace.spawn_in_terminal(spawn_in_terminal, window, cx); + cx.background_spawn(async move { + match task_status.await { + Some(Ok(status)) => { + if status.success() { + log::debug!("Vim shell exec succeeded"); + } else { + log::debug!("Vim shell exec failed, code: {:?}", status.code()); + } + } + Some(Err(e)) => log::error!("Vim shell exec failed: {e}"), + None => log::debug!("Vim shell exec got cancelled"), + } + }) + .detach(); }); return; }; diff --git a/crates/workspace/src/tasks.rs b/crates/workspace/src/tasks.rs index 0012765125..4795af827c 100644 --- a/crates/workspace/src/tasks.rs +++ b/crates/workspace/src/tasks.rs @@ -1,7 +1,7 @@ use std::process::ExitStatus; -use anyhow::{Result, anyhow}; -use gpui::{Context, Entity, Task}; +use anyhow::Result; +use gpui::{AppContext, Context, Entity, Task}; use language::Buffer; use project::TaskSourceKind; use remote::ConnectionState; @@ -68,9 +68,21 @@ impl Workspace { } if let Some(terminal_provider) = self.terminal_provider.as_ref() { - terminal_provider - .spawn(spawn_in_terminal, window, cx) - .detach_and_log_err(cx); + let task_status = terminal_provider.spawn(spawn_in_terminal, window, cx); + cx.background_spawn(async move { + match task_status.await { + Some(Ok(status)) => { + if status.success() { + log::debug!("Task spawn succeeded"); + } else { + log::debug!("Task spawn failed, code: {:?}", status.code()); + } + } + Some(Err(e)) => log::error!("Task spawn failed: {e}"), + None => log::debug!("Task spawn got cancelled"), + } + }) + .detach(); } } @@ -92,11 +104,11 @@ impl Workspace { spawn_in_terminal: SpawnInTerminal, window: &mut Window, cx: &mut Context, - ) -> Task> { + ) -> Task>> { if let Some(terminal_provider) = self.terminal_provider.as_ref() { terminal_provider.spawn(spawn_in_terminal, window, cx) } else { - Task::ready(Err(anyhow!("No terminal provider"))) + Task::ready(None) } } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 3003c0535e..bb52dd5db8 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -136,7 +136,7 @@ pub trait TerminalProvider { task: SpawnInTerminal, window: &mut Window, cx: &mut App, - ) -> Task>; + ) -> Task>>; } pub trait DebuggerProvider {