diff options
| author | Golden-Pigeon <goldenpigeon2000@gmail.com> | 2026-05-22 02:39:02 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-22 02:43:30 +0300 |
| commit | 1daf54ecbf960c42d612ed4ad2764045a606fb30 (patch) | |
| tree | c6ee19c7e8032ac77f5c00bc17bc6a1bd93d2272 /src/server | |
| parent | 0148c1379b76c5c0a9d05588c07dcb06ec32f93f (diff) | |
feat: show named session command hints
refs #199
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/autodetect.rs | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/src/server/autodetect.rs b/src/server/autodetect.rs index 976d2583..c278329d 100644 --- a/src/server/autodetect.rs +++ b/src/server/autodetect.rs @@ -85,10 +85,12 @@ fn read_server_status() -> io::Result<Option<crate::api::RuntimeStatus>> { } fn validate_running_server_compatibility() -> io::Result<()> { + let stop_command = crate::session::local_stop_command(); + let attach_command = crate::session::local_attach_command(); let Some(status) = read_server_status()? else { - return Err(io::Error::other( - "a herdr server is listening, but its status API is unavailable. Try `herdr server stop`; if that fails, stop the old server process manually, then run `herdr` again.", - )); + return Err(io::Error::other(format!( + "a herdr server is listening, but its status API is unavailable. Try `{stop_command}`; if that fails, stop the old server process manually, then run `{attach_command}` again." + ))); }; if status.protocol == Some(crate::protocol::PROTOCOL_VERSION) { @@ -96,7 +98,7 @@ fn validate_running_server_compatibility() -> io::Result<()> { } Err(io::Error::other(format!( - "herdr server is running from v{} / protocol {}, but this client is v{} / protocol {}.\nStop the old server with `herdr server stop`, then run `herdr` again.", + "herdr server is running from v{} / protocol {}, but this client is v{} / protocol {}.\nStop the old server with `{stop_command}`, then run `{attach_command}` again.", status.version.as_deref().unwrap_or("unknown"), status .protocol @@ -425,4 +427,47 @@ mod tests { std::env::remove_var(crate::api::SOCKET_PATH_ENV_VAR); let _ = std::fs::remove_dir_all(dir); } + + #[test] + fn validate_running_server_compatibility_names_session_commands_for_protocol_mismatch() { + let _guard = env_lock().lock().unwrap(); + let dir = unique_test_dir("named-protocol"); + std::fs::create_dir_all(&dir).unwrap(); + let path = dir.join("api.sock"); + let listener = UnixListener::bind(&path).unwrap(); + std::env::set_var(crate::api::SOCKET_PATH_ENV_VAR, &path); + std::env::set_var(crate::session::SESSION_ENV_VAR, "work"); + crate::session::clear_explicit_session_for_test(); + let handle = std::thread::spawn(move || { + let (mut stream, _) = listener.accept().unwrap(); + let mut request = String::new(); + BufReader::new(stream.try_clone().unwrap()) + .read_line(&mut request) + .unwrap(); + assert!(request.contains("ping")); + let body = format!( + "{{\"id\":\"autodetect:server:status\",\"result\":{{\"type\":\"pong\",\"version\":\"0.5.5\",\"protocol\":{}}}}}\n", + crate::protocol::PROTOCOL_VERSION + 1 + ); + stream.write_all(body.as_bytes()).unwrap(); + stream.flush().unwrap(); + }); + + let err = validate_running_server_compatibility().unwrap_err(); + let message = err.to_string(); + + let _ = handle.join(); + assert!( + message.contains("Stop the old server with `herdr session stop work`"), + "unexpected error: {message}" + ); + assert!( + message.contains("then run `herdr session attach work` again"), + "unexpected error: {message}" + ); + std::env::remove_var(crate::api::SOCKET_PATH_ENV_VAR); + std::env::remove_var(crate::session::SESSION_ENV_VAR); + crate::session::clear_explicit_session_for_test(); + let _ = std::fs::remove_dir_all(dir); + } } |
