Implement a mechanism for returning appbase init errors

This commit is contained in:
Łukasz Świszcz 2022-11-10 13:42:05 +01:00 committed by Bartek Wrona
parent deb2870f17
commit d0f5ce2888
6 changed files with 76 additions and 20 deletions

View File

@ -53,9 +53,12 @@ class net_plugin : public appbase::plugin<net_plugin>
int main( int argc, char** argv ) {
try {
appbase::app().register_plugin<net_plugin>(); // implict registration of chain_plugin dependency
if( !appbase::app().initialize( argc, argv ) )
return -1;
appbase::app().register_plugin<net_plugin>(); // implicit registration of chain_plugin dependency
auto initResult = appbase::app().initialize( argc, argv );
if( !initResult.should_start_loop() )
return initResult.get_result_code();
appbase::app().startup();
appbase::app().exec();
} catch ( const boost::exception& e ) {

View File

@ -243,7 +243,7 @@ void application::set_program_options()
}
}
bool application::initialize_impl(int argc, char** argv, vector<abstract_plugin*> autostart_plugins)
initialization_result application::initialize_impl(int argc, char** argv, vector<abstract_plugin*> autostart_plugins)
{
try
{
@ -252,13 +252,13 @@ bool application::initialize_impl(int argc, char** argv, vector<abstract_plugin*
if( my->_args.count( "help" ) ) {
cout << my->_app_options << "\n";
return false;
return { initialization_result::ok, false };
}
if( my->_args.count( "version" ) )
{
cout << version_info << "\n";
return false;
return { initialization_result::ok, false };
}
bfs::path data_dir;
@ -307,7 +307,7 @@ bool application::initialize_impl(int argc, char** argv, vector<abstract_plugin*
if(my->_args.count("generate-completions") > 0)
{
generate_completions();
return false;
return { initialization_result::ok, false };
}
#endif
@ -320,7 +320,7 @@ bool application::initialize_impl(int argc, char** argv, vector<abstract_plugin*
std::cout << "\t" << quoted("data-dir") << ": " << quoted(my->_data_dir.string().c_str()) << ",\n";
std::cout << "\t" << quoted("config") << ": " << quoted(config_file_name.string().c_str()) << "\n";
std::cout << "}\n";
return false;
return { initialization_result::ok, false };
}
if(my->_args.count("list-plugins") > 0)
@ -330,7 +330,7 @@ bool application::initialize_impl(int argc, char** argv, vector<abstract_plugin*
std::cout << plugin.first << "\n";
}
return false;
return { initialization_result::ok, false };
}
if(my->_args.count("plugin") > 0)
@ -350,12 +350,27 @@ bool application::initialize_impl(int argc, char** argv, vector<abstract_plugin*
bpo::notify(my->_args);
return true;
return { initialization_result::ok, true };
}
catch (const boost::program_options::validation_error& e)
{
std::cerr << "Error parsing command line: " << e.what() << "\n";
return { initialization_result::validation_error, false };
}
catch (const boost::program_options::unknown_option& e)
{
std::cerr << "Error parsing command line: " << e.what() << "\n";
return { initialization_result::unrecognised_option, false };
}
catch (const boost::program_options::error_with_option_name& e)
{
std::cerr << "Error parsing command line: " << e.what() << "\n";
return { initialization_result::error_with_option, false };
}
catch (const boost::program_options::error& e)
{
std::cerr << "Error parsing command line: " << e.what() << "\n";
return false;
return { initialization_result::unknown_command_line_error, false };
}
}

View File

@ -91,8 +91,11 @@ class plugin_b : public appbase::plugin<plugin_b>
int main( int argc, char** argv ) {
try {
appbase::app().register_plugin<plugin_b>();
if( !appbase::app().initialize( argc, argv ) )
return -1;
auto initResult = appbase::app().initialize( argc, argv );
if( !initResult.should_start_loop() )
return initResult.get_result_code();
appbase::app().startup();
appbase::app().exec();
} catch ( const boost::exception& e ) {

View File

@ -18,6 +18,38 @@ namespace appbase {
class application;
class initialization_result
{
public:
enum result {
ok,
unrecognised_option,
error_with_option,
validation_error,
unknown_command_line_error
};
initialization_result(result result, bool start_loop)
: init_result(result)
, start_loop_flag(start_loop)
{
}
int get_result_code() const
{
return init_result;
}
bool should_start_loop() const
{
return start_loop_flag;
}
private:
result init_result;
bool start_loop_flag;
};
class io_handler
{
public:
@ -72,7 +104,7 @@ namespace appbase {
* @return true if the application and plugins were initialized, false or exception on error
*/
template< typename... Plugin >
bool initialize( int argc, char** argv )
initialization_result initialize( int argc, char** argv )
{
return initialize_impl( argc, argv, { find_plugin( Plugin::name() )... } );
}
@ -151,7 +183,7 @@ namespace appbase {
template< typename Impl >
friend class plugin;
bool initialize_impl( int argc, char** argv, vector< abstract_plugin* > autostart_plugins );
initialization_result initialize_impl( int argc, char** argv, vector< abstract_plugin* > autostart_plugins );
abstract_plugin* find_plugin( const string& name )const;
abstract_plugin& get_plugin( const string& name )const;

View File

@ -71,8 +71,9 @@ int main( int argc, char** argv )
bc_converter_app.set_version_string( version_string() );
bc_converter_app.set_app_name( "blockchain_converter" );
if( !bc_converter_app.initialize( argc, argv ) )
return -1;
auto initResult = bc_converter_app.initialize( argc, argv );
if( !initResult.should_start_loop() )
return initResult.get_result_code();
bc_converter_app.startup();
bc_converter_app.exec();

View File

@ -111,13 +111,14 @@ int main( int argc, char** argv )
// These plugins are loaded regardless of the config
bool initialized = theApp.initialize<
auto initializationResult = theApp.initialize<
hive::plugins::chain::chain_plugin,
hive::plugins::p2p::p2p_plugin,
hive::plugins::webserver::webserver_plugin >
( argc, argv );
if( !initialized ) return 0;
if( !initializationResult.should_start_loop() )
return initializationResult.get_result_code();
else hive::notify_hived_status("starting");
const auto& chainPlugin = theApp.get_plugin<hive::plugins::chain::chain_plugin>();
@ -146,7 +147,8 @@ int main( int argc, char** argv )
theApp.startup();
theApp.exec();
std::cout << "exited cleanly\n";
return 0;
return initializationResult.get_result_code();
}
catch ( const boost::exception& e )
{