From 6ae8465039b7eac40efadeb4d7c757ad23cb5ad6 Mon Sep 17 00:00:00 2001 From: Tino Date: Sun, 17 Dec 2023 08:08:48 -0500 Subject: [PATCH] Add basic success check to `write_file()` and use atomic file-replacing function This checks whether `write()` returns the correct number of characters written, and uses `os.replace()` to replace the file (which is supposed to be atomic) rather than deleting the old file and _then_ renaming the new one. This may or may not help with instances of file corruption what we have seen. Since it's difficult to reproduce the issue, it's hard to be sure about that. But at the very least it shouldn't make things worse. --- modules/files.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/files.py b/modules/files.py index 3ee5615e..aa268e29 100644 --- a/modules/files.py +++ b/modules/files.py @@ -6,11 +6,11 @@ from modules.pokemon import Pokemon -def read_file(file: Path) -> str: +def read_file(file: Path) -> str | None: """ Simple function to read data from a file, return False if file doesn't exist :param file: File to read - :return: File's contents (str) + :return: File's contents (str) or None if any kind of error occurred """ try: if os.path.exists(file): @@ -38,11 +38,13 @@ def write_file(file: Path, value: str, mode: str = "w") -> bool: if not os.path.exists(directory): os.makedirs(directory) with open(tmp_file, mode=mode, encoding="utf-8") as save_file: - save_file.write(value) - if os.path.exists(file): - os.remove(file) - os.rename(tmp_file, file) - return True + characters_written = save_file.write(value) + if characters_written == len(value): + os.replace(tmp_file, file) + return True + else: + print(f"Writing {file} failed: Only {characters_written} out of {len(value)} characters written.") + return False except: return False