diff --git a/App/CMakeLists.txt b/App/CMakeLists.txt
index 29e139099e69775e0c4f25746df2af990faf265c..eda9c53e98a09ea975a64ff9c84df90e5c992bc5 100644
--- a/App/CMakeLists.txt
+++ b/App/CMakeLists.txt
@@ -8,7 +8,7 @@ else()
     set(executable_name bornagain)
 endif()
 
-set(source_files main.cpp AppOptions.cpp MessageHandler.cpp)
+set(source_files main.cpp AppOptions.cpp)
 
 # -----------------------------------------------------------------------------
 # Qt configuration
diff --git a/App/MessageHandler.cpp b/App/MessageHandler.cpp
deleted file mode 100644
index 84c8cc6c447cdc46e59776292c0002119065f72d..0000000000000000000000000000000000000000
--- a/App/MessageHandler.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      App/MessageHandler.cpp
-//! @brief     Implements function MessageHandler
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#include "App/MessageHandler.h"
-#include <QMessageBox>
-#include <iostream>
-
-//! This is set by main to be the message handler of our GUI.
-void messageHandler(QtMsgType type, const QMessageLogContext&, const QString& msg)
-{
-    switch (type) {
-    case QtDebugMsg:
-        if (msg.size() == 0) // KDE will pass a zero-length msg qstring
-            break;
-        std::cerr << "DEBUG: " << msg.toStdString() << std::endl;
-        break;
-    case QtInfoMsg:
-        std::cerr << "INFO: " << msg.toStdString() << std::endl;
-        break;
-    case QtWarningMsg:
-    default:
-        if (msg.left(4) == "QXcb")
-            return;
-        std::cerr << "WARNING: " << msg.toStdString() << std::endl;
-        // QMessageBox::warning(QApplication::activeWindow(), qAppName(), msg);
-        break;
-    case QtFatalMsg:
-        std::cerr << "FATAL: " << msg.toStdString() << std::endl;
-        qApp->restoreOverrideCursor();
-        QMessageBox msgbox(QMessageBox::Critical, "BornAgain: fatal bug",
-                           "Sorry, you encountered a fatal bug.\n"
-                           "The application will terminate.\n"
-                           "Please note the following and inform the maintainers.\n\n"
-                               + msg + "\n",
-                           QMessageBox::Ok, QApplication::activeWindow());
-        msgbox.exec();
-        qApp->quit();
-        exit(1);
-    }
-}
diff --git a/App/MessageHandler.h b/App/MessageHandler.h
deleted file mode 100644
index cfcd54a0a8787088fbbf3d22a25043420bb635d7..0000000000000000000000000000000000000000
--- a/App/MessageHandler.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      App/MessageHandler.h
-//! @brief     Declares function MessageHandler
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#ifndef BORNAGAIN_APP_MESSAGEHANDLER_H
-#define BORNAGAIN_APP_MESSAGEHANDLER_H
-
-#include <QApplication>
-
-void messageHandler(QtMsgType type, const QMessageLogContext&, const QString& msg);
-
-#endif // BORNAGAIN_APP_MESSAGEHANDLER_H
diff --git a/App/main.cpp b/App/main.cpp
index ae887e8c7c33c25bb722c101d37568533113859e..4b374e71fb0648cc39d2b24177dfc330e58accb7 100644
--- a/App/main.cpp
+++ b/App/main.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "App/AppOptions.h"
-#include "App/MessageHandler.h"
 #include "Base/Util/Assert.h"
 #include "GUI/Application/ApplicationSettings.h"
 #include "GUI/Support/Util/Path.h"
@@ -21,6 +20,7 @@
 #include "GUI/View/Main/MainWindow.h"
 #include "GUI/View/Tool/Globals.h"
 #include "config_build.h"
+#include <QApplication>
 #include <QDir>
 #include <QIcon>
 #include <QLocale>
@@ -28,15 +28,6 @@
 #include <QMetaType>
 #include <QtGlobal>
 
-auto guiFailedAssertion = [](std::string msg) {
-#ifdef BA_DEBUG
-    std::cerr << "FATAL (catched in debug mode): " << msg << std::endl;
-    std::raise(11); // abort so that we can inspect the backtrace
-#else
-    qFatal("%s", msg.c_str());
-#endif
-};
-
 int main(int argc, char* argv[])
 {
     ApplicationOptions options(argc, argv);
@@ -54,9 +45,6 @@ int main(int argc, char* argv[])
 
     ApplicationSettings applicationSettings;
 
-    qInstallMessageHandler(messageHandler);
-    failedAssertion = guiFailedAssertion;
-
     register1DDataLoaders();
 
     auto style = applicationSettings.styleToUse();
@@ -74,5 +62,15 @@ int main(int argc, char* argv[])
         win.loadProject(options.projectFile());
     win.show();
 
-    return QApplication::exec();
+    try {
+        return QApplication::exec();
+    } catch (const std::exception& ex) {
+        QMessageBox msgbox(QMessageBox::Critical, "BornAgain: fatal bug",
+                           QString("Sorry, you encountered a fatal bug.\n"
+                                   "The application will terminate.\n"
+                                   "Please note the following and inform the maintainers.\n\n")
+                           + ex.what() + "\n",
+                           QMessageBox::Ok, QApplication::activeWindow());
+        msgbox.exec();
+    }
 }
diff --git a/Base/Util/Assert.cpp b/Base/Util/Assert.cpp
deleted file mode 100644
index 39ede6f9478faede379e3e8a51f5155c75d076cd..0000000000000000000000000000000000000000
--- a/Base/Util/Assert.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      Base/Util/Assert.cpp
-//! @brief     Initializes function failedAssertion
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#include "Base/Util/Assert.h"
-
-std::function<void(std::string)> failedAssertion = [](std::string msg) {
-    throw std::runtime_error(msg);
-};
diff --git a/Base/Util/Assert.h b/Base/Util/Assert.h
index 1c4a66c3563507d605853a994033d8764050e2ee..6a6e4116bef68ecf044e1cd9325e701e1bbbedd6 100644
--- a/Base/Util/Assert.h
+++ b/Base/Util/Assert.h
@@ -19,22 +19,13 @@
 #define BORNAGAIN_BASE_UTIL_ASSERT_H
 
 #include "Wrap/WinDllMacros.h"
-#include <functional>
 #include <string>
 
-// Function called upon failed assert; set in Assert.cpp, overriden by GUI.
-extern BA_BASE_API_ std::function<void(std::string)> failedAssertion;
-
 // ASSERT macro: terminate if condition is false.
 //
 // Implementation notes:
 // - Must be declared as a macro, not a function, so that we can use preprocessor
 //   macros for informative error messages.
-// - Must terminate with a throw statement to  prevent compiler warning -Wreturn-type.
-// - In the GUI, the function pointer failedAssertion will be reset to call qFatal,
-//   which then pops up a message window (as defined by qInstallMessageHandler).
-// - No direct call to qFatal here, because we do not want core to depend on Qt,
-//   lest Python wheel becomes too difficult.
 
 #ifdef BA_DEBUG
 
@@ -42,23 +33,19 @@ extern BA_BASE_API_ std::function<void(std::string)> failedAssertion;
 #include <iostream>
 #define ASSERT(condition)                                                                          \
     if (!(condition)) {                                                                            \
-        std::cerr << "Assertion " << (#condition) << " failed in " << __FILE__ << ", line "        \
-                  << __LINE__ << std::endl;                                                        \
+        std::cerr << "Assertion " #condition " failed in " __FILE__ ", line " << __LINE__          \
+                  << std::endl;                                                                    \
         std::raise(SIGTERM); /* abort so that we can inspect the backtrace */                      \
         throw std::runtime_error("Assertion failed ... and we should never get here");             \
     }
 
 #else
 
-#include <sstream>
 #include <stdexcept>
 #define ASSERT(condition)                                                                          \
-    if (!(condition)) {                                                                            \
-        std::stringstream msg;                                                                     \
-        msg << "Assertion " << (#condition) << " failed in " << __FILE__ << ", line " << __LINE__; \
-        failedAssertion(msg.str());                                                                \
-        throw std::runtime_error("Assertion failed ... and we should never get here");             \
-    }
+    if (!(condition))                                                                              \
+        throw std::runtime_error("Assertion " #condition " failed in " __FILE__ ", line "          \
+                                 + std::to_string(__LINE__));
 
 #endif // BA_DEBUG