impr: Better recovery from exceptions thrown in main thread (#1577)

This PR improves many things which can be seen by the commit name, but
the most important thing is the addition of a popup telling the user
when an exception is thrown

![image](https://github.com/WerWolv/ImHex/assets/42669835/db796416-9cce-4aa5-ad60-c22f05b5fc73)
This commit is contained in:
WerWolv
2024-03-02 15:57:30 +01:00
parent 8e27eb8d36
commit 4a118b94cc
5 changed files with 74 additions and 10 deletions

View File

@@ -0,0 +1,46 @@
#pragma once
#include <hex/ui/popup.hpp>
#include <hex/api/localization_manager.hpp>
#include <llvm/Demangle/Demangle.h>
#include <string>
namespace hex::plugin::builtin {
class PopupCrashRecovered : public Popup<PopupCrashRecovered> {
public:
PopupCrashRecovered(const std::exception &e)
: hex::Popup<PopupCrashRecovered>("hex.builtin.popup.crash_recover.title", false),
m_errorType(typeid(e).name()),
m_errorMessage(e.what) { }
void drawContent() override {
ImGuiExt::TextFormattedWrapped("hex.builtin.popup.crash_recover.message"_lang);
ImGuiExt::TextFormattedWrapped(hex::format("Error: {}: {}", llvm::itaniumDemangle(this->m_errorType), this->m_errorMessage));
if (ImGui::Button("hex.ui.common.okay"_lang)) {
this->close();
}
}
[[nodiscard]] ImGuiWindowFlags getFlags() const override {
return ImGuiWindowFlags_AlwaysAutoResize;
}
[[nodiscard]] ImVec2 getMinSize() const override {
return scaled({ 400, 100 });
}
[[nodiscard]] ImVec2 getMaxSize() const override {
return scaled({ 600, 300 });
}
private:
std::string m_errorType, m_errorMessage;
};
}

View File

@@ -374,6 +374,8 @@
"hex.builtin.popup.exit_application.desc": "You have unsaved changes made to your Project.\nAre you sure you want to exit?",
"hex.builtin.popup.exit_application.title": "Exit Application?",
"hex.builtin.popup.waiting_for_tasks.title": "Waiting for Tasks",
"hex.builtin.popup.crash_recover.title": "Crash recovery",
"hex.builtin.popup.crash_recover.message": "An exception was thrown, but ImHex was able to catch it and advert a crash",
"hex.builtin.popup.blocking_task.title": "Running Task",
"hex.builtin.popup.blocking_task.desc": "A task is currently executing.",
"hex.builtin.popup.save_layout.title": "Save Layout",
@@ -498,7 +500,7 @@
"hex.builtin.setting.toolbar.icons": "Toolbar Icons",
"hex.builtin.shortcut.next_provider": "Select next provider",
"hex.builtin.shortcut.prev_provider": "Select previous provider",
"hex.builtin.title_bar_button.debug_build": "Debug build",
"hex.builtin.title_bar_button.debug_build": "Debug build\nShift+Click to crash using exception\nCtrl+Click to crash using signal",
"hex.builtin.title_bar_button.feedback": "Leave Feedback",
"hex.builtin.tools.ascii_table": "ASCII table",
"hex.builtin.tools.ascii_table.octal": "Show octal",

View File

@@ -21,6 +21,7 @@
#include <popups/popup_question.hpp>
#include <content/popups/popup_tasks_waiting.hpp>
#include <content/popups/popup_unsaved_changes.hpp>
#include <content/popups/popup_crash_recovered.hpp>
namespace hex::plugin::builtin {
@@ -48,6 +49,10 @@ namespace hex::plugin::builtin {
void registerEventHandlers() {
static bool imhexClosing = false;
EventCrashRecovered::subscribe([](const std::exception &e) {
PopupCrashRecovered::open(e);
});
EventWindowClosing::subscribe([](GLFWwindow *window) {
imhexClosing = false;
if (ImHexApi::Provider::isDirty() && !imhexClosing) {