aboutsummaryrefslogtreecommitdiff
path: root/src/persist/io.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-15 21:17:32 +0300
committerGitHub <noreply@github.com>2026-09-15 21:17:32 +0300
commit4428e1664d8d897ce2f914777c0fe060cf334c84 (patch)
treeb0074802c17cd609f77c1a230a2fd7f2b396d943 /src/persist/io.rs
parentf70a1f835ef614f5e1ad1bde76d4629c650fd192 (diff)
fix: preserve unloaded sessions before replacement (#4190)
refs #4125
Diffstat (limited to 'src/persist/io.rs')
-rw-r--r--src/persist/io.rs83
1 files changed, 29 insertions, 54 deletions
diff --git a/src/persist/io.rs b/src/persist/io.rs
index 3344f5ec..6f5ed459 100644
--- a/src/persist/io.rs
+++ b/src/persist/io.rs
@@ -7,7 +7,7 @@ use super::snapshot::{
SessionSnapshot, SNAPSHOT_VERSION,
};
-fn session_path() -> PathBuf {
+pub(super) fn session_path() -> PathBuf {
crate::session::data_dir().join("session.json")
}
@@ -60,19 +60,14 @@ fn save_json_to_path<T: serde::Serialize>(path: &Path, snapshot: &T) -> std::io:
Ok(())
}
-pub(super) fn save_to_paths(
- session_path: &Path,
- history_path: &Path,
- snapshot: &SessionSnapshot,
+pub(super) fn save_history_to_path(
+ path: &Path,
history: Option<&SessionHistorySnapshot>,
) -> std::io::Result<()> {
- save_to_path(session_path, snapshot)?;
- if let Some(history) = history {
- save_json_to_path(history_path, history)?;
- } else {
- clear_path(history_path)?;
+ match history {
+ Some(history) => save_json_to_path(path, history),
+ None => clear_path(path),
}
- Ok(())
}
pub(super) fn clear_path(path: &Path) -> std::io::Result<()> {
@@ -83,26 +78,6 @@ pub(super) fn clear_path(path: &Path) -> std::io::Result<()> {
}
}
-pub fn save(snapshot: &SessionSnapshot, history: Option<&SessionHistorySnapshot>) {
- let path = session_path();
- let history_path = session_history_path();
- if let Err(err) = save_to_paths(&path, &history_path, snapshot, history) {
- crate::logging::session_save_failed(&path, &err.to_string());
- return;
- }
- crate::logging::session_saved(&path, snapshot.workspaces.len());
-}
-
-pub fn clear() {
- let path = session_path();
- if let Err(err) = clear_path(&path) {
- crate::logging::session_clear_failed(&path, &err.to_string());
- return;
- }
- clear_history();
- crate::logging::session_cleared(&path);
-}
-
pub fn clear_history() {
let path = session_history_path();
if let Err(err) = clear_path(&path) {
@@ -112,13 +87,20 @@ pub fn clear_history() {
pub fn load() -> Option<SessionSnapshot> {
let path = session_path();
- if !path.exists() {
- return None;
- }
let content = match std::fs::read_to_string(&path) {
Ok(content) => content,
+ Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
+ tracing::info!(
+ event = "persist.restore", subsystem = "persist", outcome = "missing",
+ path = %path.display(), "session file is missing"
+ );
+ return None;
+ }
Err(err) => {
- warn!(err = %err, "failed to read session file");
+ warn!(
+ event = "persist.restore", subsystem = "persist", outcome = "read_error",
+ path = %path.display(), err = %err, "failed to read session file"
+ );
return None;
}
};
@@ -128,14 +110,17 @@ pub fn load() -> Option<SessionSnapshot> {
if let Some(version) = snapshot_file_version(&content) {
if version > SNAPSHOT_VERSION {
warn!(
- file_version = version,
- supported = SNAPSHOT_VERSION,
+ event = "persist.restore", subsystem = "persist", outcome = "unsupported_version",
+ path = %path.display(), file_version = version, supported = SNAPSHOT_VERSION,
"session file is from a newer herdr version, ignoring"
);
return None;
}
}
- warn!(err = %err, "failed to parse session file, ignoring");
+ warn!(
+ event = "persist.restore", subsystem = "persist", outcome = "parse_error",
+ path = %path.display(), err = %err, "failed to parse session file, ignoring"
+ );
None
}
}
@@ -231,13 +216,8 @@ mod tests {
fn save_to_paths_writes_pane_history_only_to_history_file() {
let (session_path, history_path) = temp_session_paths("split-history");
- save_to_paths(
- &session_path,
- &history_path,
- &empty_snapshot(),
- Some(&history_snapshot("split-secret")),
- )
- .unwrap();
+ save_to_path(&session_path, &empty_snapshot()).unwrap();
+ save_history_to_path(&history_path, Some(&history_snapshot("split-secret"))).unwrap();
let session = std::fs::read_to_string(&session_path).unwrap();
let history = std::fs::read_to_string(&history_path).unwrap();
@@ -249,15 +229,10 @@ mod tests {
#[test]
fn save_to_paths_removes_stale_history_when_history_is_disabled() {
let (session_path, history_path) = temp_session_paths("clear-history");
- save_to_paths(
- &session_path,
- &history_path,
- &empty_snapshot(),
- Some(&history_snapshot("stale-secret")),
- )
- .unwrap();
-
- save_to_paths(&session_path, &history_path, &empty_snapshot(), None).unwrap();
+ save_to_path(&session_path, &empty_snapshot()).unwrap();
+ save_history_to_path(&history_path, Some(&history_snapshot("stale-secret"))).unwrap();
+
+ save_history_to_path(&history_path, None).unwrap();
assert!(session_path.exists());
assert!(!history_path.exists());