Skip to content

Commit af806ba

Browse files
committed
try writeStringSafe as solution to save issues
1 parent 1131d5a commit af806ba

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

loader/include/Geode/utils/file.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace geode::utils::file {
4949
}
5050

5151
GEODE_DLL Result<> writeString(std::filesystem::path const& path, std::string const& data);
52+
GEODE_DLL Result<> writeStringSafe(std::filesystem::path const& path, std::string const& data);
5253
GEODE_DLL Result<> writeBinary(std::filesystem::path const& path, ByteVector const& data);
5354

5455
template <class T>

loader/src/loader/ModImpl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ Result<> Mod::Impl::saveData() {
218218
// saveData is expected to be synchronous, and always called from GD thread
219219
ModStateEvent(m_self, ModEventType::DataSaved).post();
220220

221-
auto res = utils::file::writeString(m_saveDirPath / "settings.json", json.dump());
221+
auto res = utils::file::writeStringSafe(m_saveDirPath / "settings.json", json.dump());
222222
if (!res) {
223223
log::error("Unable to save settings: {}", res.unwrapErr());
224224
}
225-
auto res2 = utils::file::writeString(m_saveDirPath / "saved.json", m_saved.dump());
225+
auto res2 = utils::file::writeStringSafe(m_saveDirPath / "saved.json", m_saved.dump());
226226
if (!res2) {
227227
log::error("Unable to save values: {}", res2.unwrapErr());
228228
}

loader/src/utils/file.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,43 @@ Result<> utils::file::writeString(std::filesystem::path const& path, std::string
8181
}
8282

8383
file << data;
84+
if (file.fail()) {
85+
file.close();
86+
return Err("Failed to write to file");
87+
}
88+
8489
file.close();
90+
91+
return Ok();
92+
}
93+
94+
Result<> utils::file::writeStringSafe(std::filesystem::path const& path, std::string const& data) {
95+
std::error_code ec;
96+
97+
auto tmpPath = path;
98+
tmpPath += ".tmp";
99+
100+
auto res = utils::file::writeString(tmpPath, data);
101+
if (!res) {
102+
if (std::filesystem::exists(tmpPath, ec)) {
103+
std::filesystem::remove(tmpPath, ec);
104+
}
105+
return res;
106+
}
107+
108+
if (std::filesystem::exists(path, ec)) {
109+
std::filesystem::remove(path, ec);
110+
}
111+
112+
if (ec) {
113+
return Err("Unable to remove old file: " + ec.message());
114+
}
115+
116+
std::filesystem::rename(tmpPath, path, ec);
117+
if (ec) {
118+
return Err("Unable to rename temporary file: " + ec.message());
119+
}
120+
85121
return Ok();
86122
}
87123

0 commit comments

Comments
 (0)