SaveState: Fix error handling in SaveState_ZipToDisk
Some checks are pending
🐧 Linux Builds / AppImage (push) Waiting to run
🐧 Linux Builds / Flatpak (push) Waiting to run
🍎 MacOS Builds / Defaults (push) Waiting to run
🖥️ Windows Builds / Lint VS Project Files (push) Waiting to run
🖥️ Windows Builds / SSE4 (push) Blocked by required conditions
🖥️ Windows Builds / AVX2 (push) Blocked by required conditions
🖥️ Windows Builds / CMake (push) Waiting to run

This commit is contained in:
chaoticgd 2025-12-09 16:32:55 +00:00 committed by Ty
parent 743b0b11d8
commit cf4412ecbe
3 changed files with 28 additions and 15 deletions

View File

@ -1039,14 +1039,18 @@ static bool SaveState_AddToZip(zip_t* zf, ArchiveEntryList* srclist, SaveStateSc
return true;
}
bool SaveState_ZipToDisk(std::unique_ptr<ArchiveEntryList> srclist, std::unique_ptr<SaveStateScreenshotData> screenshot, const char* filename)
bool SaveState_ZipToDisk(
std::unique_ptr<ArchiveEntryList> srclist, std::unique_ptr<SaveStateScreenshotData> screenshot,
const char* filename, Error* error)
{
zip_error_t ze = {};
zip_source_t* zs = zip_source_file_create(filename, 0, 0, &ze);
zip_t* zf = nullptr;
if (zs && !(zf = zip_open_from_source(zs, ZIP_CREATE | ZIP_TRUNCATE, &ze)))
{
Console.Error("Failed to open zip file '%s' for save state: %s", filename, zip_error_strerror(&ze));
Error::SetStringFmt(error,
TRANSLATE_FS("SaveState", "Failed to open zip file '{}' for save state: {}."),
filename, zip_error_strerror(&ze));
// have to clean up source
zip_source_free(zs);
@ -1056,13 +1060,21 @@ bool SaveState_ZipToDisk(std::unique_ptr<ArchiveEntryList> srclist, std::unique_
// discard zip file if we fail saving something
if (!SaveState_AddToZip(zf, srclist.get(), screenshot.get()))
{
Console.Error("Failed to save state to zip file '%s'", filename);
Error::SetStringFmt(error,
TRANSLATE_FS("SaveState", "Failed to save state to zip file '{}'."), filename);
zip_discard(zf);
return false;
}
// force the zip to close, this is the expensive part with libzip.
zip_close(zf);
if (zip_close(zf) != 0)
{
Error::SetStringFmt(error,
TRANSLATE_FS("SaveState", "Failed to save state to zip file '{}': {}."), filename, zip_strerror(zf));
zip_discard(zf);
return false;
}
return true;
}

View File

@ -54,7 +54,9 @@ class ArchiveEntryList;
// These functions assume that the caller has paused the core thread.
extern std::unique_ptr<ArchiveEntryList> SaveState_DownloadState(Error* error);
extern std::unique_ptr<SaveStateScreenshotData> SaveState_SaveScreenshot();
extern bool SaveState_ZipToDisk(std::unique_ptr<ArchiveEntryList> srclist, std::unique_ptr<SaveStateScreenshotData> screenshot, const char* filename);
extern bool SaveState_ZipToDisk(
std::unique_ptr<ArchiveEntryList> srclist, std::unique_ptr<SaveStateScreenshotData> screenshot,
const char* filename, Error* error);
extern bool SaveState_ReadScreenshot(const std::string& filename, u32* out_width, u32* out_height, std::vector<u32>* out_pixels);
extern bool SaveState_UnzipFromDisk(const std::string& filename, Error* error);

View File

@ -1909,19 +1909,18 @@ void VMManager::ZipSaveState(std::unique_ptr<ArchiveEntryList> elist,
{
Common::Timer timer;
if (SaveState_ZipToDisk(std::move(elist), std::move(screenshot), filename))
Error error;
if (!SaveState_ZipToDisk(std::move(elist), std::move(screenshot), filename, &error))
{
if (slot_for_message >= 0 && VMManager::HasValidVM())
{
Host::AddIconOSDMessage("SaveState", ICON_FA_FLOPPY_DISK,
fmt::format(TRANSLATE_FS("VMManager", "Saved state to slot {}."), slot_for_message),
Host::OSD_QUICK_DURATION);
}
error_callback(error.GetDescription());
return;
}
else
if (slot_for_message >= 0 && VMManager::HasValidVM())
{
error_callback(fmt::format(
TRANSLATE_FS("VMManager", "Cannot zip state."), slot_for_message));
Host::AddIconOSDMessage(fmt::format("SaveStateSlot{}", slot_for_message), ICON_FA_FLOPPY_DISK,
fmt::format(TRANSLATE_FS("VMManager", "Saved state to slot {}."), slot_for_message),
Host::OSD_QUICK_DURATION);
}
DevCon.WriteLn("Zipping save state to '%s' took %.2f ms", filename, timer.GetTimeMilliseconds());