From 13e5d8097c77b8f4429293eaf311828bd1a4c014 Mon Sep 17 00:00:00 2001
From: Johannes Altmanninger <aclopte@gmail.com>
Date: Wed, 9 Oct 2024 12:31:18 +0200
Subject: [PATCH] Log more history_file errors, and add more context

See #10300
---
 src/history.rs      | 35 ++++++++++++++++++++++++++---------
 src/wutil/fileid.rs |  6 ++++++
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/src/history.rs b/src/history.rs
index 4544bdcfa..d00149665 100644
--- a/src/history.rs
+++ b/src/history.rs
@@ -16,7 +16,10 @@
 //! 5. The chaos_mode boolean can be set to true to do things like lower buffer sizes which can
 //! trigger race conditions. This is useful for testing.
 
-use crate::{common::cstr2wcstring, env::EnvVar, wcstringutil::trim};
+use crate::{
+    common::cstr2wcstring, env::EnvVar, wcstringutil::trim,
+    wutil::fileid::file_id_for_path_or_error,
+};
 use std::{
     borrow::Cow,
     collections::{BTreeMap, HashMap, HashSet},
@@ -621,10 +624,10 @@ impl HistoryImpl {
             }
         }
         if let Some(err) = err {
-            FLOGF!(
+            FLOG!(
                 history_file,
-                "Error %d when writing to temporary history file",
-                err.raw_os_error().unwrap_or_default()
+                "Error writing to temporary history file:",
+                err
             );
 
             false
@@ -670,6 +673,9 @@ impl HistoryImpl {
                 OFlag::O_RDONLY | OFlag::O_CREAT,
                 HISTORY_FILE_MODE,
             );
+            if let Err(err) = target_file_before {
+                FLOG!(history_file, "Error opening history file:", err);
+            }
 
             let orig_file_id = target_file_before
                 .as_ref()
@@ -697,7 +703,15 @@ impl HistoryImpl {
                 unsafe {
                     Self::maybe_lock_file(target_fd_after, LOCK_EX);
                 }
-                new_file_id = file_id_for_path(&target_name);
+                new_file_id = match file_id_for_path_or_error(&target_name) {
+                    Ok(file_id) => file_id,
+                    Err(err) => {
+                        if err.kind() != std::io::ErrorKind::NotFound {
+                            FLOG!(history_file, "Error re-opening history file:", err);
+                        }
+                        INVALID_FILE_ID
+                    }
+                }
             }
 
             let can_replace_file = new_file_id == orig_file_id || new_file_id == INVALID_FILE_ID;
@@ -1108,13 +1122,16 @@ impl HistoryImpl {
         // destination file descriptor, since it destroys the name and the file.
         self.clear();
 
-        let Ok(mut dst_file) = wopen_cloexec(
+        let mut dst_file = match wopen_cloexec(
             &new_file,
             OFlag::O_WRONLY | OFlag::O_CREAT,
             HISTORY_FILE_MODE,
-        ) else {
-            FLOG!(history_file, "Error when writing history file");
-            return;
+        ) {
+            Ok(file) => file,
+            Err(err) => {
+                FLOG!(history_file, "Error when writing history file:", err);
+                return;
+            }
         };
 
         let mut buf = [0; libc::BUFSIZ as usize];
diff --git a/src/wutil/fileid.rs b/src/wutil/fileid.rs
index b160710bb..3b6109b86 100644
--- a/src/wutil/fileid.rs
+++ b/src/wutil/fileid.rs
@@ -85,3 +85,9 @@ pub fn file_id_for_path_narrow(path: &CStr) -> FileId {
         .map(FileId::from_md)
         .unwrap_or(INVALID_FILE_ID)
 }
+
+pub fn file_id_for_path_or_error(path: &wstr) -> std::io::Result<FileId> {
+    let path = wcs2zstring(path);
+    let path = OsStr::from_bytes(path.to_bytes());
+    fs::metadata(path).map(|md| FileId::from_md(&md))
+}