From 26db26e416318e17a6e7f3f196ec72109fb37998 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Tue, 30 Jun 2026 19:48:56 +0300 Subject: fix: keep remote sessions alive across disconnects --- src/client/mod.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'src/client') diff --git a/src/client/mod.rs b/src/client/mod.rs index 59b7b114..4e0a54ec 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -280,7 +280,14 @@ impl std::fmt::Display for ClientError { Ok(()) } ClientError::ConnectionLost(err) => { - write!(f, "lost connection to server: {err}") + if let Ok(reattach_command) = std::env::var(crate::remote::REATTACH_COMMAND_ENV_VAR) + { + write!(f, "lost connection to remote Herdr: {err}")?; + write!(f, "\nIf the remote server survived the SSH or network drop, its panes may still be running.")?; + write!(f, "\nRun `{reattach_command}` to reattach") + } else { + write!(f, "lost connection to server: {err}") + } } ClientError::Protocol(err) => { write!(f, "protocol error: {err}") @@ -2372,6 +2379,8 @@ mod tests { #[test] fn client_error_display_connection_lost() { + let _guard = env_lock().lock().unwrap(); + let _env = EnvVarsRemovedGuard::new(&[crate::remote::REATTACH_COMMAND_ENV_VAR]); let err = ClientError::ConnectionLost(io::Error::new(io::ErrorKind::BrokenPipe, "broken pipe")); let msg = err.to_string(); @@ -2381,6 +2390,30 @@ mod tests { ); } + #[test] + fn client_error_display_remote_connection_lost_has_reattach_hint() { + let _guard = env_lock().lock().unwrap(); + let _remote_env = EnvVarGuard::set( + crate::remote::REATTACH_COMMAND_ENV_VAR, + "herdr --remote host --session work", + ); + let err = + ClientError::ConnectionLost(io::Error::new(io::ErrorKind::BrokenPipe, "broken pipe")); + let msg = err.to_string(); + assert!( + msg.contains("lost connection to remote Herdr"), + "should mention remote connection loss: {msg}" + ); + assert!( + msg.contains("panes may still be running"), + "should explain possible persistence: {msg}" + ); + assert!( + msg.contains("Run `herdr --remote host --session work` to reattach"), + "should show remote reattach command: {msg}" + ); + } + #[test] fn sound_from_notify_message_maps_done() { assert_eq!( -- cgit v1.2.3