1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

Merge pull request #17665 from janisozaur/more-info-on-save-failure

Collect more info in case of save failure
This commit is contained in:
Michał Janiszewski
2022-08-05 00:59:47 +02:00
committed by GitHub
8 changed files with 106 additions and 15 deletions

View File

@@ -640,6 +640,30 @@ public:
_platformUiContext->ShowMessageBox(_window, message);
}
int32_t ShowMessageBox(
const std::string& title, const std::string& message, const std::vector<std::string>& options) override
{
auto message_box_button_data = std::make_unique<SDL_MessageBoxButtonData[]>(options.size());
for (size_t i = 0; i < options.size(); i++)
{
message_box_button_data[i].buttonid = static_cast<int>(i);
message_box_button_data[i].text = options[i].c_str();
}
SDL_MessageBoxData message_box_data{};
message_box_data.window = _window;
message_box_data.title = title.c_str();
message_box_data.message = message.c_str();
message_box_data.numbuttons = static_cast<int>(options.size());
message_box_data.buttons = message_box_button_data.get();
int buttonid{};
SDL_ShowMessageBox(&message_box_data, &buttonid);
return buttonid;
}
bool HasMenuSupport() override
{
return _platformUiContext->HasMenuSupport();

View File

@@ -541,6 +541,18 @@ namespace OpenRCT2
const std::string& path, bool loadTitleScreenOnFail = false, bool asScenario = false) final override
{
log_verbose("Context::LoadParkFromFile(%s)", path.c_str());
// Register the file for crash upload if it asserts while loading.
crash_register_additional_file("load_park", path);
// Deregister park file in case it was processed without hitting an assert.
struct foo
{
~foo()
{
crash_unregister_additional_file("load_park");
}
} f;
try
{
if (String::Equals(Path::GetExtension(path), ".sea", true))

View File

@@ -184,9 +184,11 @@ namespace OpenRCT2
{
return;
}
if (fwrite(buffer, static_cast<size_t>(length), 1, _file) != 1)
if (auto count = fwrite(buffer, static_cast<size_t>(length), 1, _file); count != 1)
{
throw IOException("Unable to write to file.");
std::string error = "Unable to write " + std::to_string(length) + " bytes to file. Count = " + std::to_string(count)
+ ", errno = " + std::to_string(errno);
throw IOException(error);
}
uint64_t position = GetPosition();

View File

@@ -49,6 +49,7 @@
#include "../scenario/Scenario.h"
#include "../scenario/ScenarioRepository.h"
#include "../scripting/ScriptEngine.h"
#include "../ui/UiContext.h"
#include "../world/Climate.h"
#include "../world/Entrance.h"
#include "../world/Map.h"
@@ -2312,6 +2313,31 @@ int32_t scenario_save(u8string_view path, int32_t flags)
catch (const std::exception& e)
{
log_error(e.what());
Formatter ft;
ft.Add<const char*>(e.what());
context_show_error(STR_FILE_DIALOG_TITLE_SAVE_SCENARIO, STR_STRING, ft);
gfx_invalidate_screen();
auto ctx = OpenRCT2::GetContext();
auto uictx = ctx->GetUiContext();
std::string title = "Error while saving";
std::string message
= "There was an error while saving scenario.\nhttps://github.com/OpenRCT2/OpenRCT2/issues/17664\nWe would like to "
"collect more information about this issue, if this did not happen due to missing permissions, lack of space, "
"etc. please consider submitting a bug report. To collect information we would like to trigger an assert.";
std::string report_bug_button = "Report bug, trigger an assert, potentially terminating the game";
std::string skip_button = "Skip reporting, let me continue";
std::vector<std::string> buttons{ std::move(report_bug_button), std::move(skip_button) };
int choice = uictx->ShowMessageBox(title, message, buttons);
if (choice == 0)
{
Guard::Assert(false, "Error while saving: %s", e.what());
}
}
gfx_invalidate_screen();

View File

@@ -47,13 +47,14 @@
# define WSZ(x) L"" x
# ifdef OPENRCT2_COMMIT_SHA1_SHORT
const wchar_t* _wszCommitSha1Short = WSZ(OPENRCT2_COMMIT_SHA1_SHORT);
static const wchar_t* _wszCommitSha1Short = WSZ(OPENRCT2_COMMIT_SHA1_SHORT);
# else
const wchar_t* _wszCommitSha1Short = WSZ("");
static const wchar_t* _wszCommitSha1Short = WSZ("");
# endif
// OPENRCT2_ARCHITECTURE is required to be defined in version.h
const wchar_t* _wszArchitecture = WSZ(OPENRCT2_ARCHITECTURE);
static const wchar_t* _wszArchitecture = WSZ(OPENRCT2_ARCHITECTURE);
static std::map<std::wstring, std::wstring> _uploadFiles;
# define BACKTRACE_TOKEN L"0ca992e20aca116b5e090fd2eaff6e7b5c8225f778fd8f4e77cb077d70329324"
@@ -114,8 +115,6 @@ static bool OnCrash(
return succeeded;
}
std::map<std::wstring, std::wstring> uploadFiles;
// Get filenames
wchar_t dumpFilePath[MAX_PATH];
wchar_t saveFilePath[MAX_PATH];
@@ -147,7 +146,7 @@ static bool OnCrash(
// advertise it officially.
/*
uploadFiles[L"upload_file_minidump"] = dumpFilePathGZIP;
_uploadFiles[L"upload_file_minidump"] = dumpFilePathGZIP;
*/
}
fclose(input);
@@ -161,7 +160,7 @@ static bool OnCrash(
{
std::wcscpy(dumpFilePath, dumpFilePathNew);
}
uploadFiles[L"upload_file_minidump"] = dumpFilePath;
_uploadFiles[L"upload_file_minidump"] = dumpFilePath;
// Compress to gzip-compatible stream
@@ -195,13 +194,13 @@ static bool OnCrash(
// Compress the save
if (savedGameDumped)
{
uploadFiles[L"attachment_park.park"] = saveFilePath;
_uploadFiles[L"attachment_park.park"] = saveFilePath;
}
auto configFilePathUTF8 = String::ToUtf8(configFilePath);
if (config_save(configFilePathUTF8))
{
uploadFiles[L"attachment_config.ini"] = configFilePath;
_uploadFiles[L"attachment_config.ini"] = configFilePath;
}
// janisozaur: https://github.com/OpenRCT2/OpenRCT2/pull/17634
@@ -219,7 +218,7 @@ static bool OnCrash(
if (!screenshotPath.empty())
{
auto screenshotPathW = String::ToWideChar(screenshotPath.c_str());
uploadFiles[L"attachment_screenshot.png"] = screenshotPathW;
_uploadFiles[L"attachment_screenshot.png"] = screenshotPathW;
}
}
@@ -229,7 +228,7 @@ static bool OnCrash(
bool record_copied = CopyFileW(parkReplayPathW.c_str(), recordFilePathNew, true);
if (record_copied)
{
uploadFiles[L"attachment_replay.parkrep"] = recordFilePathNew;
_uploadFiles[L"attachment_replay.parkrep"] = recordFilePathNew;
}
else
{
@@ -242,7 +241,7 @@ static bool OnCrash(
printf("Uploading minidump in silent mode...\n");
int error;
std::wstring response;
UploadMinidump(uploadFiles, error, response);
UploadMinidump(_uploadFiles, error, response);
return succeeded;
}
@@ -260,7 +259,7 @@ static bool OnCrash(
{
int error;
std::wstring response;
bool ok = UploadMinidump(uploadFiles, error, response);
bool ok = UploadMinidump(_uploadFiles, error, response);
if (!ok)
{
const wchar_t* MessageFormat2 = L"There was a problem while uploading the dump. Please upload it manually to "
@@ -340,3 +339,21 @@ CExceptionHandler crash_init()
return nullptr;
#endif // USE_BREAKPAD
}
void crash_register_additional_file(const std::string& key, const std::string& path)
{
#ifdef USE_BREAKPAD
_uploadFiles[String::ToWideChar(key.c_str())] = String::ToWideChar(path.c_str());
#endif // USE_BREAKPAD
}
void crash_unregister_additional_file(const std::string& key)
{
#ifdef USE_BREAKPAD
auto it = _uploadFiles.find(String::ToWideChar(key.c_str()));
if (it != _uploadFiles.end())
{
_uploadFiles.erase(it);
}
#endif // USE_BREAKPAD
}

View File

@@ -9,7 +9,11 @@
#pragma once
#include <string>
using CExceptionHandler = void*;
extern bool gOpenRCT2SilentBreakpad;
CExceptionHandler crash_init();
void crash_register_additional_file(const std::string& key, const std::string& path);
void crash_unregister_additional_file(const std::string& key);

View File

@@ -90,6 +90,10 @@ namespace OpenRCT2::Ui
void ShowMessageBox(const std::string& /*message*/) override
{
}
int32_t ShowMessageBox(const std::string&, const std::string&, const std::vector<std::string>&) override
{
return -1;
}
bool HasMenuSupport() override
{
return false;

View File

@@ -120,6 +120,8 @@ namespace OpenRCT2
virtual void TriggerResize() abstract;
virtual void ShowMessageBox(const std::string& message) abstract;
virtual int32_t ShowMessageBox(
const std::string& title, const std::string& message, const std::vector<std::string>& options) abstract;
virtual bool HasMenuSupport() abstract;
// Creates a menu with a series of options, returns the index of the selected option