Skip to content

Commit 67923d6

Browse files
author
MarcoFalke
committed
Merge #16366: init: Use InitError for all errors in bitcoind/qt
fa6f402 Call node->initError instead of InitError from GUI code (Russell Yanofsky) fad2502 init: Use InitError for all errors in bitcoind/qt (MarcoFalke) Pull request description: Using the same InitError for startup error in the daemon and the gui makes it possible to run the tests with the gui again: ```sh BITCOIND=bitcoin-qt ./test/functional/test_runner.py feature_includeconf feature_config_args ACKs for top commit: hebasto: ACK fa6f402 ryanofsky: utACK fa6f402. Only changes since last review are removing more includes and adding Node::initError method to avoid accessing node `InitError` function and global variables from GUI code. Tree-SHA512: bd19e08dcea4019dfe40356bc5c63cb583cefed54b6c9dcfb82f1b5b00308d8e2b363549afcaea5e93bf83864dbe0917400c3b70f43a8a5bdff45c9cd34cc294
2 parents e6e99d4 + fa6f402 commit 67923d6

File tree

8 files changed

+33
-38
lines changed

8 files changed

+33
-38
lines changed

src/bitcoind.cpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
#include <clientversion.h>
1212
#include <compat.h>
1313
#include <fs.h>
14-
#include <interfaces/chain.h>
1514
#include <init.h>
15+
#include <interfaces/chain.h>
1616
#include <noui.h>
1717
#include <shutdown.h>
18+
#include <ui_interface.h>
19+
#include <util/strencodings.h>
1820
#include <util/system.h>
1921
#include <util/threadnames.h>
20-
#include <util/strencodings.h>
21-
22-
#include <stdio.h>
2322

2423
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
2524

@@ -70,8 +69,7 @@ static bool AppInit(int argc, char* argv[])
7069
SetupServerArgs();
7170
std::string error;
7271
if (!gArgs.ParseParameters(argc, argv, error)) {
73-
tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error.c_str());
74-
return false;
72+
return InitError(strprintf("Error parsing command line arguments: %s\n", error));
7573
}
7674

7775
// Process help and version before taking care about datadir
@@ -96,26 +94,22 @@ static bool AppInit(int argc, char* argv[])
9694
{
9795
if (!fs::is_directory(GetDataDir(false)))
9896
{
99-
tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str());
100-
return false;
97+
return InitError(strprintf("Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "")));
10198
}
10299
if (!gArgs.ReadConfigFiles(error, true)) {
103-
tfm::format(std::cerr, "Error reading configuration file: %s\n", error.c_str());
104-
return false;
100+
return InitError(strprintf("Error reading configuration file: %s\n", error));
105101
}
106102
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
107103
try {
108104
SelectParams(gArgs.GetChainName());
109105
} catch (const std::exception& e) {
110-
tfm::format(std::cerr, "Error: %s\n", e.what());
111-
return false;
106+
return InitError(strprintf("%s\n", e.what()));
112107
}
113108

114109
// Error out when loose non-argument tokens are encountered on command line
115110
for (int i = 1; i < argc; i++) {
116111
if (!IsSwitchChar(argv[i][0])) {
117-
tfm::format(std::cerr, "Error: Command line contains unexpected token '%s', see bitcoind -h for a list of options.\n", argv[i]);
118-
return false;
112+
return InitError(strprintf("Command line contains unexpected token '%s', see bitcoind -h for a list of options.\n", argv[i]));
119113
}
120114
}
121115

@@ -146,19 +140,17 @@ static bool AppInit(int argc, char* argv[])
146140
#pragma GCC diagnostic push
147141
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
148142
#endif
149-
tfm::format(std::cout, "Bitcoin server starting\n");
143+
tfm::format(std::cout, PACKAGE_NAME "daemon starting\n");
150144

151145
// Daemonize
152146
if (daemon(1, 0)) { // don't chdir (1), do close FDs (0)
153-
tfm::format(std::cerr, "Error: daemon() failed: %s\n", strerror(errno));
154-
return false;
147+
return InitError(strprintf("daemon() failed: %s\n", strerror(errno)));
155148
}
156149
#if defined(MAC_OSX)
157150
#pragma GCC diagnostic pop
158151
#endif
159152
#else
160-
tfm::format(std::cerr, "Error: -daemon is not supported on this operating system\n");
161-
return false;
153+
return InitError("-daemon is not supported on this operating system\n");
162154
#endif // HAVE_DECL_DAEMON
163155
}
164156
// Lock data directory after daemonization

src/interfaces/node.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class NodeImpl : public Node
5454
{
5555
public:
5656
NodeImpl() { m_interfaces.chain = MakeChain(); }
57+
void initError(const std::string& message) override { InitError(message); }
5758
bool parseParameters(int argc, const char* const argv[], std::string& error) override
5859
{
5960
return gArgs.ParseParameters(argc, argv, error);

src/interfaces/node.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class Node
3838
public:
3939
virtual ~Node() {}
4040

41+
//! Send init error.
42+
virtual void initError(const std::string& message) = 0;
43+
4144
//! Set command line arguments.
4245
virtual bool parseParameters(int argc, const char* const argv[], std::string& error) = 0;
4346

src/qt/bitcoin.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
#include <qt/bitcoingui.h>
1111

1212
#include <chainparams.h>
13-
#include <qt/clientmodel.h>
1413
#include <fs.h>
14+
#include <qt/clientmodel.h>
1515
#include <qt/guiconstants.h>
1616
#include <qt/guiutil.h>
1717
#include <qt/intro.h>
@@ -30,15 +30,12 @@
3030
#include <interfaces/handler.h>
3131
#include <interfaces/node.h>
3232
#include <noui.h>
33-
#include <util/threadnames.h>
3433
#include <ui_interface.h>
3534
#include <uint256.h>
3635
#include <util/system.h>
36+
#include <util/threadnames.h>
3737

3838
#include <memory>
39-
#include <stdint.h>
40-
41-
#include <boost/thread.hpp>
4239

4340
#include <QApplication>
4441
#include <QDebug>
@@ -462,8 +459,11 @@ int GuiMain(int argc, char* argv[])
462459
SetupUIArgs();
463460
std::string error;
464461
if (!node->parseParameters(argc, argv, error)) {
462+
node->initError(strprintf("Error parsing command line arguments: %s\n", error));
463+
// Create a message box, because the gui has neither been created nor has subscribed to core signals
465464
QMessageBox::critical(nullptr, PACKAGE_NAME,
466-
QObject::tr("Error parsing command line arguments: %1.").arg(QString::fromStdString(error)));
465+
// message can not be translated because translations have not been initialized
466+
QString::fromStdString("Error parsing command line arguments: %1.").arg(QString::fromStdString(error)));
467467
return EXIT_FAILURE;
468468
}
469469

@@ -499,11 +499,13 @@ int GuiMain(int argc, char* argv[])
499499
/// - Do not call GetDataDir(true) before this step finishes
500500
if (!fs::is_directory(GetDataDir(false)))
501501
{
502+
node->initError(strprintf("Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "")));
502503
QMessageBox::critical(nullptr, PACKAGE_NAME,
503504
QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
504505
return EXIT_FAILURE;
505506
}
506507
if (!node->readConfigFiles(error)) {
508+
node->initError(strprintf("Error reading configuration file: %s\n", error));
507509
QMessageBox::critical(nullptr, PACKAGE_NAME,
508510
QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error)));
509511
return EXIT_FAILURE;
@@ -519,6 +521,7 @@ int GuiMain(int argc, char* argv[])
519521
try {
520522
node->selectParams(gArgs.GetChainName());
521523
} catch(std::exception &e) {
524+
node->initError(strprintf("%s\n", e.what()));
522525
QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: %1").arg(e.what()));
523526
return EXIT_FAILURE;
524527
}

src/qt/bitcoin.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include <QApplication>
1313
#include <memory>
14-
#include <vector>
1514

1615
class BitcoinGUI;
1716
class ClientModel;

src/qt/bitcoingui.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@
3636
#include <ui_interface.h>
3737
#include <util/system.h>
3838

39-
#include <iostream>
40-
#include <memory>
41-
4239
#include <QAction>
4340
#include <QApplication>
4441
#include <QComboBox>

test/functional/feature_config_args.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def test_config_file_parser(self):
2222
conf.write('includeconf={}\n'.format(inc_conf_file_path))
2323

2424
self.nodes[0].assert_start_raises_init_error(
25-
expected_msg='Error parsing command line arguments: Invalid parameter -dash_cli',
25+
expected_msg='Error: Error parsing command line arguments: Invalid parameter -dash_cli',
2626
extra_args=['-dash_cli=1'],
2727
)
2828
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
@@ -33,7 +33,7 @@ def test_config_file_parser(self):
3333

3434
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
3535
conf.write('-dash=1\n')
36-
self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading -')
36+
self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading -')
3737

3838
with open(inc_conf_file_path, 'w', encoding='utf8') as conf:
3939
conf.write("wallet=foo\n")
@@ -46,19 +46,19 @@ def test_config_file_parser(self):
4646

4747
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
4848
conf.write('nono\n')
49-
self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: nono, if you intended to specify a negated option, use nono=1 instead')
49+
self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 1: nono, if you intended to specify a negated option, use nono=1 instead')
5050

5151
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
5252
conf.write('server=1\nrpcuser=someuser\nrpcpassword=some#pass')
53-
self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
53+
self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
5454

5555
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
5656
conf.write('server=1\nrpcuser=someuser\nmain.rpcpassword=some#pass')
57-
self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
57+
self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
5858

5959
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
6060
conf.write('server=1\nrpcuser=someuser\n[main]\nrpcpassword=some#pass')
61-
self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 4, using # in rpcpassword can be ambiguous and should be avoided')
61+
self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 4, using # in rpcpassword can be ambiguous and should be avoided')
6262

6363
inc_conf_file2_path = os.path.join(self.nodes[0].datadir, 'include2.conf')
6464
with open(os.path.join(self.nodes[0].datadir, 'bitcoin.conf'), 'a', encoding='utf-8') as conf:

test/functional/feature_includeconf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def run_test(self):
4343

4444
self.log.info("-includeconf cannot be used as command-line arg")
4545
self.stop_node(0)
46-
self.nodes[0].assert_start_raises_init_error(extra_args=["-includeconf=relative2.conf"], expected_msg="Error parsing command line arguments: -includeconf cannot be used from commandline; -includeconf=relative2.conf")
46+
self.nodes[0].assert_start_raises_init_error(extra_args=["-includeconf=relative2.conf"], expected_msg="Error: Error parsing command line arguments: -includeconf cannot be used from commandline; -includeconf=relative2.conf")
4747

4848
self.log.info("-includeconf cannot be used recursively. subversion should end with 'main; relative)/'")
4949
with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "a", encoding="utf8") as f:
@@ -59,11 +59,11 @@ def run_test(self):
5959
# Commented out as long as we ignore invalid arguments in configuration files
6060
#with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "w", encoding="utf8") as f:
6161
# f.write("foo=bar\n")
62-
#self.nodes[0].assert_start_raises_init_error(expected_msg="Error reading configuration file: Invalid configuration value foo")
62+
#self.nodes[0].assert_start_raises_init_error(expected_msg="Error: Error reading configuration file: Invalid configuration value foo")
6363

6464
self.log.info("-includeconf cannot be invalid path")
6565
os.remove(os.path.join(self.options.tmpdir, "node0", "relative.conf"))
66-
self.nodes[0].assert_start_raises_init_error(expected_msg="Error reading configuration file: Failed to include configuration file relative.conf")
66+
self.nodes[0].assert_start_raises_init_error(expected_msg="Error: Error reading configuration file: Failed to include configuration file relative.conf")
6767

6868
self.log.info("multiple -includeconf args can be used from the base config file. subversion should end with 'main; relative; relative2)/'")
6969
with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "w", encoding="utf8") as f:

0 commit comments

Comments
 (0)