From f042fd992170ee8a50a7f596f1c9cdd9600b8583 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 5 Oct 2013 15:12:35 +0300 Subject: [PATCH 1/1] Redesign uncaught exception handling to allow external reporters This helps keep UI code out of the core library. It was becoming a problem especially on OS X where including an Objective-C wrapper around NSAlert would have broken Builder's bootstrap. Libmspgui will acquire a class that will present graphical error dialogs on each platform. --- source/core/application.cpp | 16 ++++++++++++++-- source/core/application.h | 2 -- source/core/unix/application.cpp | 17 ----------------- source/core/windows/application.cpp | 16 ---------------- source/debug/errorreporter.cpp | 20 ++++++++++++++++++++ source/debug/errorreporter.h | 29 +++++++++++++++++++++++++++++ 6 files changed, 63 insertions(+), 37 deletions(-) delete mode 100644 source/core/unix/application.cpp delete mode 100644 source/core/windows/application.cpp create mode 100644 source/debug/errorreporter.cpp create mode 100644 source/debug/errorreporter.h diff --git a/source/core/application.cpp b/source/core/application.cpp index ebd928b..43bb023 100644 --- a/source/core/application.cpp +++ b/source/core/application.cpp @@ -1,4 +1,7 @@ +#include #include +#include +#include #include #include "application.h" #include "getopt.h" @@ -53,9 +56,18 @@ int Application::run(int argc, char **argv, void *data) } catch(const exception &e) { - delete app_; + bool handled = false; + if(const Debug::ErrorReporter *er = Debug::ErrorReporter::get_current()) + handled = er->report_uncaught_exception(e); - display_exception(e); + if(!handled) + { + IO::print(IO::cerr, "An uncaught exception occurred.\n"); + IO::print(IO::cerr, " type: %s\n", Debug::demangle(typeid(e).name())); + IO::print(IO::cerr, " what(): %s\n", e.what()); + } + + delete app_; return 124; } diff --git a/source/core/application.h b/source/core/application.h index 1384085..e1d3a8b 100644 --- a/source/core/application.h +++ b/source/core/application.h @@ -66,8 +66,6 @@ private: /** Static wrapper function to call a member function of the Application instance. */ static void sighandler_(int); - - static void display_exception(const std::exception &); }; diff --git a/source/core/unix/application.cpp b/source/core/unix/application.cpp deleted file mode 100644 index 7f45fbc..0000000 --- a/source/core/unix/application.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include -#include "application.h" - -using namespace std; - -namespace Msp { - -void Application::display_exception(const exception &e) -{ - IO::print(IO::cerr, "An uncaught exception occurred.\n"); - IO::print(IO::cerr, " type: %s\n", Debug::demangle(typeid(e).name())); - IO::print(IO::cerr, " what(): %s\n", e.what()); -} - -} // namespace Msp diff --git a/source/core/windows/application.cpp b/source/core/windows/application.cpp deleted file mode 100644 index ed8702a..0000000 --- a/source/core/windows/application.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include -#include "application.h" - -using namespace std; - -namespace Msp { - -void Application::display_exception(const exception &e) -{ - string msg = Debug::demangle(typeid(e).name())+":\n"+e.what(); - MessageBoxA(0, msg.c_str(), "Uncaught exception", MB_OK|MB_ICONERROR); -} - -} // namespace Msp diff --git a/source/debug/errorreporter.cpp b/source/debug/errorreporter.cpp new file mode 100644 index 0000000..d4d51bc --- /dev/null +++ b/source/debug/errorreporter.cpp @@ -0,0 +1,20 @@ +#include "errorreporter.h" + +namespace Msp { +namespace Debug { + +ErrorReporter *ErrorReporter::current = 0; + +ErrorReporter::ErrorReporter(): + prev(current) +{ + current = this; +} + +ErrorReporter::~ErrorReporter() +{ + current = prev; +} + +} // namespace Debug +} // namespace Msp diff --git a/source/debug/errorreporter.h b/source/debug/errorreporter.h new file mode 100644 index 0000000..b0385ff --- /dev/null +++ b/source/debug/errorreporter.h @@ -0,0 +1,29 @@ +#ifndef MSP_DEBUG_ERRORREPORTER_H_ +#define MSP_DEBUG_ERRORREPORTER_H_ + +#include + +namespace Msp { +namespace Debug { + +class ErrorReporter +{ +private: + ErrorReporter *prev; + + static ErrorReporter *current; + +protected: + ErrorReporter(); +public: + virtual ~ErrorReporter(); + + static const ErrorReporter *get_current() { return current; } + + virtual bool report_uncaught_exception(const std::exception &) const = 0; +}; + +} // namespace Debug +} // namespace Msp + +#endif -- 2.43.0