Skip to content
Snippets Groups Projects
Commit d76cbec6 authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

Failed assertion throws runtime_error; message box moved to GUI main loop try..catch wrapper

parent 3fff6fd4
No related branches found
No related tags found
2 merge requests!1525Updates from r20.0,!1518Failed assertion throws runtime_error; message box moved to GUI main loop try..catch wrapper (#496)
...@@ -8,7 +8,7 @@ else() ...@@ -8,7 +8,7 @@ else()
set(executable_name bornagain) set(executable_name bornagain)
endif() endif()
set(source_files main.cpp AppOptions.cpp MessageHandler.cpp) set(source_files main.cpp AppOptions.cpp)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Qt configuration # Qt configuration
......
// ************************************************************************************************
//
// 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);
}
}
// ************************************************************************************************
//
// 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
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
// ************************************************************************************************ // ************************************************************************************************
#include "App/AppOptions.h" #include "App/AppOptions.h"
#include "App/MessageHandler.h"
#include "Base/Util/Assert.h" #include "Base/Util/Assert.h"
#include "GUI/Application/ApplicationSettings.h" #include "GUI/Application/ApplicationSettings.h"
#include "GUI/Support/Util/Path.h" #include "GUI/Support/Util/Path.h"
...@@ -21,6 +20,7 @@ ...@@ -21,6 +20,7 @@
#include "GUI/View/Main/MainWindow.h" #include "GUI/View/Main/MainWindow.h"
#include "GUI/View/Tool/Globals.h" #include "GUI/View/Tool/Globals.h"
#include "config_build.h" #include "config_build.h"
#include <QApplication>
#include <QDir> #include <QDir>
#include <QIcon> #include <QIcon>
#include <QLocale> #include <QLocale>
...@@ -28,15 +28,6 @@ ...@@ -28,15 +28,6 @@
#include <QMetaType> #include <QMetaType>
#include <QtGlobal> #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[]) int main(int argc, char* argv[])
{ {
ApplicationOptions options(argc, argv); ApplicationOptions options(argc, argv);
...@@ -54,9 +45,6 @@ int main(int argc, char* argv[]) ...@@ -54,9 +45,6 @@ int main(int argc, char* argv[])
ApplicationSettings applicationSettings; ApplicationSettings applicationSettings;
qInstallMessageHandler(messageHandler);
failedAssertion = guiFailedAssertion;
register1DDataLoaders(); register1DDataLoaders();
auto style = applicationSettings.styleToUse(); auto style = applicationSettings.styleToUse();
...@@ -74,5 +62,15 @@ int main(int argc, char* argv[]) ...@@ -74,5 +62,15 @@ int main(int argc, char* argv[])
win.loadProject(options.projectFile()); win.loadProject(options.projectFile());
win.show(); 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();
}
} }
// ************************************************************************************************
//
// 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);
};
...@@ -19,22 +19,13 @@ ...@@ -19,22 +19,13 @@
#define BORNAGAIN_BASE_UTIL_ASSERT_H #define BORNAGAIN_BASE_UTIL_ASSERT_H
#include "Wrap/WinDllMacros.h" #include "Wrap/WinDllMacros.h"
#include <functional>
#include <string> #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. // ASSERT macro: terminate if condition is false.
// //
// Implementation notes: // Implementation notes:
// - Must be declared as a macro, not a function, so that we can use preprocessor // - Must be declared as a macro, not a function, so that we can use preprocessor
// macros for informative error messages. // 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 #ifdef BA_DEBUG
...@@ -42,23 +33,19 @@ extern BA_BASE_API_ std::function<void(std::string)> failedAssertion; ...@@ -42,23 +33,19 @@ extern BA_BASE_API_ std::function<void(std::string)> failedAssertion;
#include <iostream> #include <iostream>
#define ASSERT(condition) \ #define ASSERT(condition) \
if (!(condition)) { \ if (!(condition)) { \
std::cerr << "Assertion " << (#condition) << " failed in " << __FILE__ << ", line " \ std::cerr << "Assertion " #condition " failed in " __FILE__ ", line " << __LINE__ \
<< __LINE__ << std::endl; \ << std::endl; \
std::raise(SIGTERM); /* abort so that we can inspect the backtrace */ \ std::raise(SIGTERM); /* abort so that we can inspect the backtrace */ \
throw std::runtime_error("Assertion failed ... and we should never get here"); \ throw std::runtime_error("Assertion failed ... and we should never get here"); \
} }
#else #else
#include <sstream>
#include <stdexcept> #include <stdexcept>
#define ASSERT(condition) \ #define ASSERT(condition) \
if (!(condition)) { \ if (!(condition)) \
std::stringstream msg; \ throw std::runtime_error("Assertion " #condition " failed in " __FILE__ ", line " \
msg << "Assertion " << (#condition) << " failed in " << __FILE__ << ", line " << __LINE__; \ + std::to_string(__LINE__));
failedAssertion(msg.str()); \
throw std::runtime_error("Assertion failed ... and we should never get here"); \
}
#endif // BA_DEBUG #endif // BA_DEBUG
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment