Skip to content

Handle initialization errors #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 48 additions & 8 deletions src/qml/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ void SetupUIArgs(ArgsManager& argsman)
argsman.AddArg("-resetguisettings", "Reset all settings changed in the GUI", ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
argsman.AddArg("-splash", strprintf("Show splash screen on startup (default: %u)", DEFAULT_SPLASHSCREEN), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
}

bool InitErrorMessageBox(
const bilingual_str& message,
[[maybe_unused]] const std::string& caption,
[[maybe_unused]] unsigned int style)
{
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("message", QString::fromStdString(message.translated));
engine.load(QUrl(QStringLiteral("qrc:///qml/pages/initerrormessage.qml")));
qGuiApp->exec();
return false;
}
} // namespace


Expand All @@ -42,31 +54,59 @@ int QmlGuiMain(int argc, char* argv[])
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);

// Parse command-line options. We do this after qt in order to show an error if there are problems parsing these.
auto handler_message_box = ::uiInterface.ThreadSafeMessageBox_connect(InitErrorMessageBox);

NodeContext node_context;

/// Parse command-line options. We do this after qt in order to show an error if there are problems parsing these.
node_context.args = &gArgs;
SetupServerArgs(gArgs);
SetupUIArgs(gArgs);
std::string error;
if (!gArgs.ParseParameters(argc, argv, error)) {
InitError(strprintf(Untranslated("Error parsing command line arguments: %s\n"), error));
InitError(strprintf(Untranslated("Cannot parse command line arguments: %s\n"), error));
return EXIT_FAILURE;
}

/// Determine availability of data directory.
if (!CheckDataDirOption()) {
InitError(strprintf(Untranslated("Specified data directory \"%s\" does not exist.\n"), gArgs.GetArg("-datadir", "")));
return EXIT_FAILURE;
}

CheckDataDirOption();
/// Read and parse bitcoin.conf file.
if (!gArgs.ReadConfigFiles(error, true)) {
InitError(strprintf(Untranslated("Cannot parse configuration file: %s\n"), error));
return EXIT_FAILURE;
}

gArgs.ReadConfigFiles(error, true);
/// Check for chain settings (Params() calls are only valid after this clause).
try {
SelectParams(gArgs.GetChainName());
} catch(std::exception &e) {
InitError(Untranslated(strprintf("%s\n", e.what())));
return EXIT_FAILURE;
}

SelectParams(gArgs.GetChainName());
/// Read and parse settings.json file.
if (!gArgs.InitSettings(error)) {
InitError(Untranslated(error));
return EXIT_FAILURE;
}

// Default printtoconsole to false for the GUI. GUI programs should not
// print to the console unnecessarily.
gArgs.SoftSetBoolArg("-printtoconsole", false);
InitLogging(gArgs);
InitParameterInteraction(gArgs);

NodeContext node_context;
node_context.args = &gArgs;
std::unique_ptr<interfaces::Node> node = interfaces::MakeNode(&node_context);
node->baseInitialize();
if (!node->baseInitialize()) {
// A dialog with detailed error will have been shown by InitError().
return EXIT_FAILURE;
}

handler_message_box.disconnect();

NodeModel node_model;
InitExecutor init_executor{*node};
Expand Down
1 change: 1 addition & 0 deletions src/qml/bitcoin_qml.qrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/qml">
<file>pages/initerrormessage.qml</file>
<file>pages/stub.qml</file>
</qresource>
</RCC>
11 changes: 11 additions & 0 deletions src/qml/pages/initerrormessage.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import QtQuick 2.12
import QtQuick.Dialogs 1.3

MessageDialog {
id: messageDialog
title: "Bitcoin Core TnG"
icon: StandardIcon.Critical
text: message
onAccepted: Qt.quit()
Component.onCompleted: visible = true
}
5 changes: 0 additions & 5 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,11 +452,6 @@ int GuiMain(int argc, char* argv[])
NodeContext node_context;
std::unique_ptr<interfaces::Node> node = interfaces::MakeNode(&node_context);

// Subscribe to global signals from core
boost::signals2::scoped_connection handler_message_box = ::uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox);
boost::signals2::scoped_connection handler_question = ::uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion);
boost::signals2::scoped_connection handler_init_message = ::uiInterface.InitMessage_connect(noui_InitMessage);

// Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory

/// 1. Basic Qt initialization (not dependent on parameters or configuration)
Expand Down
4 changes: 4 additions & 0 deletions src/qt/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <qt/bitcoin.h>
#endif // USE_QML

#include <noui.h>
#include <util/system.h>
#include <util/threadnames.h>
#include <util/translation.h>
Expand Down Expand Up @@ -39,6 +40,9 @@ int main(int argc, char* argv[])
SetupEnvironment();
util::ThreadSetInternalName("main");

// Subscribe to global signals from core.
noui_connect();

#if USE_QML
return QmlGuiMain(argc, argv);
#else
Expand Down