Fix resume session with an invalid path crash (#2453)

This commit is contained in:
Zane
2025-05-06 15:23:00 -07:00
committed by GitHub
parent 95c31250df
commit 392a101078
2 changed files with 59 additions and 2 deletions
+11 -1
View File
@@ -103,7 +103,17 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session {
.interact().expect("Failed to get user input");
if change_workdir {
std::env::set_current_dir(metadata.working_dir).unwrap();
if !metadata.working_dir.exists() {
output::render_error(&format!(
"Cannot switch to original working directory - {} no longer exists",
style(metadata.working_dir.display()).cyan()
));
} else if let Err(e) = std::env::set_current_dir(&metadata.working_dir) {
output::render_error(&format!(
"Failed to switch to original working directory: {}",
e
));
}
}
}
}
+48 -1
View File
@@ -62,6 +62,12 @@ impl<'de> Deserialize<'de> for SessionMetadata {
let helper = Helper::deserialize(deserializer)?;
// Get working dir, falling back to home if not specified or if specified dir doesn't exist
let working_dir = helper
.working_dir
.filter(|path| path.exists())
.unwrap_or_else(get_home_dir);
Ok(SessionMetadata {
description: helper.description,
message_count: helper.message_count,
@@ -71,13 +77,20 @@ impl<'de> Deserialize<'de> for SessionMetadata {
accumulated_total_tokens: helper.accumulated_total_tokens,
accumulated_input_tokens: helper.accumulated_input_tokens,
accumulated_output_tokens: helper.accumulated_output_tokens,
working_dir: helper.working_dir.unwrap_or_else(get_home_dir),
working_dir,
})
}
}
impl SessionMetadata {
pub fn new(working_dir: PathBuf) -> Self {
// If working_dir doesn't exist, fall back to home directory
let working_dir = if !working_dir.exists() {
get_home_dir()
} else {
working_dir
};
Self {
working_dir,
description: String::new(),
@@ -563,4 +576,38 @@ mod tests {
Ok(())
}
#[test]
fn test_invalid_working_dir() -> Result<()> {
let dir = tempdir()?;
let file_path = dir.path().join("test.jsonl");
// Create metadata with non-existent directory
let invalid_dir = PathBuf::from("/path/that/does/not/exist");
let metadata = SessionMetadata::new(invalid_dir.clone());
// Should fall back to home directory
assert_ne!(metadata.working_dir, invalid_dir);
assert_eq!(metadata.working_dir, get_home_dir());
// Test deserialization of invalid directory
let messages = vec![Message::user().with_text("test")];
save_messages_with_metadata(&file_path, &metadata, &messages)?;
// Modify the file to include invalid directory
let contents = fs::read_to_string(&file_path)?;
let mut lines: Vec<String> = contents.lines().map(String::from).collect();
lines[0] = lines[0].replace(
&get_home_dir().to_string_lossy().into_owned(),
&invalid_dir.to_string_lossy().into_owned(),
);
fs::write(&file_path, lines.join("\n"))?;
// Read back - should fall back to home dir
let read_metadata = read_metadata(&file_path)?;
assert_ne!(read_metadata.working_dir, invalid_dir);
assert_eq!(read_metadata.working_dir, get_home_dir());
Ok(())
}
}