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:
iTrooz
2024-03-01 18:21:15 +01:00
committed by GitHub
parent 78f8e5055e
commit 97f5175c84
5 changed files with 73 additions and 10 deletions

View File

@@ -23,7 +23,7 @@
static void subscribe(void *token, Event::Callback function) { EventManager::subscribe<event_name>(token, function); } \
static void unsubscribe(const EventManager::EventList::iterator &token) noexcept { EventManager::unsubscribe(token); } \
static void unsubscribe(void *token) noexcept { EventManager::unsubscribe<event_name>(token); } \
static void post(auto &&...args) noexcept { EventManager::post<event_name>(std::forward<decltype(args)>(args)...); } \
static void post(auto &&...args) { EventManager::post<event_name>(std::forward<decltype(args)>(args)...); } \
};
#define EVENT_DEF(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, true, __VA_ARGS__)
@@ -72,11 +72,12 @@ namespace hex {
explicit Event(Callback func) noexcept : m_func(std::move(func)) { }
void operator()(Params... params) const noexcept {
void operator()(std::string_view eventName, Params... params) const {
try {
m_func(params...);
} catch (const std::exception &e) {
log::error("An exception occurred while handling event: {}", e.what());
log::error("An exception occurred while handling event {}: {}", eventName, e.what());
throw;
}
}
@@ -173,12 +174,12 @@ namespace hex {
* @param args Arguments to pass to the event
*/
template<impl::EventType E>
static void post(auto &&...args) noexcept {
static void post(auto && ...args) {
std::scoped_lock lock(getEventMutex());
for (const auto &[id, event] : getEvents()) {
if (id == E::Id) {
(*static_cast<E *const>(event.get()))(std::forward<decltype(args)>(args)...);
(*static_cast<E *const>(event.get()))(wolv::type::getTypeName<E>(), std::forward<decltype(args)>(args)...);
}
}
@@ -310,4 +311,8 @@ namespace hex {
*/
EVENT_DEF(MovePerProviderData, prv::Provider *, prv::Provider *);
/**
* Called when ImHex managed to catch an error in a general try/catch to prevent/recover from a crash
*/
EVENT_DEF(EventCrashRecovered, const std::exception &);
}