Fix 5 high-risk bugs from 13th audit pass
- cleanup_placeholder now removes 1-byte marker files on error (regression)
- {width}/{height} template vars replaced with "0" when dimensions unavailable
- Text watermark width multiplier 0.6->1.0 to prevent CJK/wide char clipping
- cmd_undo preserves history entries when trash operations fail
- cmd_watch_remove exits on write failure instead of silent discard
This commit is contained in:
@@ -535,13 +535,15 @@ fn cmd_undo(count: usize) {
|
||||
let undo_count = count.min(entries.len());
|
||||
let to_undo = entries.split_off(entries.len() - undo_count);
|
||||
let mut total_trashed = 0;
|
||||
let mut failed_entries = Vec::new();
|
||||
|
||||
for entry in &to_undo {
|
||||
for entry in to_undo {
|
||||
if entry.output_files.is_empty() {
|
||||
println!(
|
||||
"Batch from {} has no recorded output files - cannot undo",
|
||||
entry.timestamp
|
||||
);
|
||||
failed_entries.push(entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -550,11 +552,13 @@ fn cmd_undo(count: usize) {
|
||||
entry.total, entry.input_dir
|
||||
);
|
||||
|
||||
let mut batch_trashed = 0;
|
||||
for file_path in &entry.output_files {
|
||||
let path = PathBuf::from(file_path);
|
||||
if path.exists() {
|
||||
match trash::delete(&path) {
|
||||
Ok(()) => {
|
||||
batch_trashed += 1;
|
||||
total_trashed += 1;
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -563,9 +567,17 @@ fn cmd_undo(count: usize) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keep entry in history if no files were trashed
|
||||
if batch_trashed == 0 {
|
||||
failed_entries.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove undone entries from history
|
||||
// Re-add entries where trash failed so they can be retried
|
||||
entries.extend(failed_entries);
|
||||
|
||||
// Write updated history
|
||||
if let Err(e) = history.write_all(&entries) {
|
||||
eprintln!("Warning: failed to update history after undo: {}", e);
|
||||
}
|
||||
@@ -706,8 +718,17 @@ fn cmd_watch_remove(path: &str) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Ok(json) = serde_json::to_string_pretty(&watches) {
|
||||
let _ = std::fs::write(&watches_path, json);
|
||||
match serde_json::to_string_pretty(&watches) {
|
||||
Ok(json) => {
|
||||
if let Err(e) = std::fs::write(&watches_path, json) {
|
||||
eprintln!("Failed to write watch config: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to serialize watch config: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
println!("Removed watch folder: {}", path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user