diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h index c200a3d0..dd599cf8 100644 --- a/contrib/epee/include/misc_language.h +++ b/contrib/epee/include/misc_language.h @@ -371,7 +371,7 @@ namespace misc_utils } -#define ON_EXIT misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler +#define ON_FUNC_EXIT misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler template< typename t_contaner, typename t_redicate> diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index d2c536ba..5e0c7a1a 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -356,7 +356,7 @@ public: //update threads name to see connection context where errors came from std::string original_prefix = epee::log_space::log_singletone::get_thread_log_prefix(); epee::log_space::log_singletone::set_thread_log_prefix(original_prefix + "[" + epee::net_utils::print_connection_context_short(m_connection_context) + "]"); - ON_EXIT([&](){epee::log_space::log_singletone::set_thread_log_prefix(original_prefix); }); + ON_FUNC_EXIT([&](){epee::log_space::log_singletone::set_thread_log_prefix(original_prefix); }); //create_scope_leave_handler() diff --git a/src/wallet/plain_wallet_api.cpp b/src/wallet/plain_wallet_api.cpp index 8c0f9efd..d242c760 100644 --- a/src/wallet/plain_wallet_api.cpp +++ b/src/wallet/plain_wallet_api.cpp @@ -44,6 +44,37 @@ ok_response.result.return_code = API_RETURN_CODE_UNINITIALIZED; \ return sanitized_store_to_json(ok_response); \ } + +#define PLAIN_WALLET_BEGIN_TRY_ENTRY() try { +#define PLAIN_WALLET_CATCH() } \ + catch (const std::exception& e) \ + { \ + LOG_ERROR("Exception during plain wallet call [" << __func__ << "]: " << e.what()); \ + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); \ + ok_response.result.return_code = std::string(API_RETURN_CODE_INTERNAL_ERROR) + " " + e.what(); \ + return sanitized_store_to_json(ok_response); \ + } \ + catch (...) \ + { \ + LOG_ERROR("Unknown exception during plain wallet call [" << __func__ << "]"); \ + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); \ + ok_response.result.return_code = API_RETURN_CODE_INTERNAL_ERROR; \ + return sanitized_store_to_json(ok_response); \ + } + + + + + + + + + + + + + + namespace plain_wallet { void deinit(); @@ -187,11 +218,13 @@ namespace plain_wallet std::string reset() { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); inst_ptr->gwm.quick_clear_wallets_no_save(); epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); ok_response.result.return_code = API_RETURN_CODE_OK; return sanitized_store_to_json(ok_response); + PLAIN_WALLET_CATCH(); } @@ -360,9 +393,11 @@ namespace plain_wallet std::string get_connectivity_status() { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); return inst_ptr->gwm.get_connectivity_status(); + PLAIN_WALLET_CATCH(); } std::string get_version() @@ -458,6 +493,7 @@ namespace plain_wallet std::string open(const std::string& path, const std::string& password) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); std::string full_path = get_wallets_folder() + path; @@ -478,11 +514,13 @@ namespace plain_wallet } error_response err_result = AUTO_VAL_INIT(err_result); err_result.error.code = rsp; - return sanitized_store_to_json(err_result); + return sanitized_store_to_json(err_result); + PLAIN_WALLET_CATCH(); } std::string restore(const std::string& seed, const std::string& path, const std::string& password, const std::string& seed_password) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); std::string full_path = get_wallets_folder() + path; @@ -503,10 +541,12 @@ namespace plain_wallet error_response err_result = AUTO_VAL_INIT(err_result); err_result.error.code = rsp; return sanitized_store_to_json(err_result); + PLAIN_WALLET_CATCH(); } std::string generate(const std::string& path, const std::string& password) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); std::string full_path = get_wallets_folder() + path; @@ -527,36 +567,45 @@ namespace plain_wallet error_response err_result = AUTO_VAL_INIT(err_result); err_result.error.code = rsp; return sanitized_store_to_json(err_result); + PLAIN_WALLET_CATCH(); } std::string get_opened_wallets() { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); epee::json_rpc::response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response); inst_ptr->gwm.get_opened_wallets(ok_response.result); return sanitized_store_to_json(ok_response); + PLAIN_WALLET_CATCH(); } std::string close_wallet(hwallet h) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); std::string r = "{\"response\": \""; r += inst_ptr->gwm.close_wallet(h); r += "\"}"; return r; + PLAIN_WALLET_CATCH(); } std::string get_wallet_status(hwallet h) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); return inst_ptr->gwm.get_wallet_status(h); + PLAIN_WALLET_CATCH(); } std::string invoke(hwallet h, const std::string& params) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); return inst_ptr->gwm.invoke(h, params); + PLAIN_WALLET_CATCH(); } void put_result(uint64_t job_id, const std::string& res) @@ -591,12 +640,15 @@ namespace plain_wallet std::string async_call(const std::string& method_name, uint64_t instance_id, const std::string& params) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); std::function async_callback; uint64_t job_id = inst_ptr->gjobs_counter++; async_callback = [job_id, instance_id, method_name, params]() { + ON_FUNC_EXIT([&]() {LOG_PRINT_L2("Worker for job " << job_id << " finished"); }); + std::string res_str = sync_call(method_name, instance_id, params); put_result(job_id, res_str); }; @@ -605,10 +657,12 @@ namespace plain_wallet t.detach(); LOG_PRINT_L2("[ASYNC_CALL]: started " << method_name << ", job id: " << job_id); return std::string("{ \"job_id\": ") + std::to_string(job_id) + "}"; + PLAIN_WALLET_CATCH(); } std::string handle_reset_connection_url(const std::string& url) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); inst_ptr->gwm.set_remote_node_url(url); @@ -617,10 +671,12 @@ namespace plain_wallet view::api_response ar = AUTO_VAL_INIT(ar); ar.error_code = API_RETURN_CODE_OK; return sanitized_store_to_json(ar); + PLAIN_WALLET_CATCH(); } std::string handle_proxy_to_daemon(const std::string& data) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); tools::wallet_public::COMMAND_PROXY_TO_DAEMON::request req; tools::wallet_public::COMMAND_PROXY_TO_DAEMON::response res; @@ -644,12 +700,14 @@ namespace plain_wallet res.base64_body = epee::string_encoding::base64_encode(response_body); res.response_code = response_code; return sanitized_store_to_json(res); + PLAIN_WALLET_CATCH(); } std::string handle_run_wallet(uint64_t instance_id) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); @@ -667,10 +725,12 @@ namespace plain_wallet view::api_response ar = AUTO_VAL_INIT(ar); ar.error_code = inst_ptr->gwm.run_wallet(instance_id); return sanitized_store_to_json(ar); + PLAIN_WALLET_CATCH(); } std::string handle_configure(const std::string& settings_json) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); configure_object conf = AUTO_VAL_INIT(conf); configure_response conf_resp = AUTO_VAL_INIT(conf_resp); @@ -683,92 +743,113 @@ namespace plain_wallet inst_ptr->postponed_run_wallet = conf.postponed_run_wallet; conf_resp.status = API_RETURN_CODE_OK; return sanitized_store_to_json(conf_resp); + PLAIN_WALLET_CATCH(); } std::string sync_call(const std::string& method_name, uint64_t instance_id, const std::string& params) { std::string res; - if (method_name == "close") - { + try { + + if (method_name == "close") + { close_wallet(instance_id); view::api_responce_return_code rc = AUTO_VAL_INIT(rc); rc.return_code = API_RETURN_CODE_OK; res = sanitized_store_to_json(rc); - } - else if (method_name == "open") - { - view::open_wallet_request owr = AUTO_VAL_INIT(owr); - if (!epee::serialization::load_t_from_json(owr, params)) - { - view::api_response ar = AUTO_VAL_INIT(ar); - ar.error_code = "Wrong parameter"; - res = sanitized_store_to_json(ar); - }else - { - res = open(owr.path, owr.pass); } - } - else if (method_name == "restore") - { - view::restore_wallet_request rwr = AUTO_VAL_INIT(rwr); - if (!epee::serialization::load_t_from_json(rwr, params)) + else if (method_name == "open") { - view::api_response ar = AUTO_VAL_INIT(ar); - ar.error_code = "Wrong parameter"; - res = sanitized_store_to_json(ar); + view::open_wallet_request owr = AUTO_VAL_INIT(owr); + if (!epee::serialization::load_t_from_json(owr, params)) + { + view::api_response ar = AUTO_VAL_INIT(ar); + ar.error_code = "Wrong parameter"; + res = sanitized_store_to_json(ar); + } + else + { + res = open(owr.path, owr.pass); + } + } + else if (method_name == "restore") + { + view::restore_wallet_request rwr = AUTO_VAL_INIT(rwr); + if (!epee::serialization::load_t_from_json(rwr, params)) + { + view::api_response ar = AUTO_VAL_INIT(ar); + ar.error_code = "Wrong parameter"; + res = sanitized_store_to_json(ar); + } + else + { + res = restore(rwr.seed_phrase, rwr.path, rwr.pass, rwr.seed_pass); + } + } + else if (method_name == "get_seed_phrase_info") + { + view::seed_info_param sip = AUTO_VAL_INIT(sip); + if (!epee::serialization::load_t_from_json(sip, params)) + { + view::api_response ar = AUTO_VAL_INIT(ar); + ar.error_code = "Wrong parameter"; + res = sanitized_store_to_json(ar); + } + else + { + view::api_response_t rsp = AUTO_VAL_INIT(rsp); + rsp.error_code = tools::get_seed_phrase_info(sip.seed_phrase, sip.seed_password, rsp.response_data); + res = sanitized_store_to_json(rsp); + } + } + else if (method_name == "invoke") + { + res = invoke(instance_id, params); + } + else if (method_name == "get_wallet_status") + { + res = get_wallet_status(instance_id); + } + else if (method_name == "configure") + { + res = handle_configure(params); + } + else if (method_name == "reset_connection_url") + { + res = handle_reset_connection_url(params); + } + else if (method_name == "run_wallet") + { + res = handle_run_wallet(instance_id); + } + else if (method_name == "proxy_to_daemon") + { + res = handle_proxy_to_daemon(params); } else - { - res = restore(rwr.seed_phrase, rwr.path, rwr.pass, rwr.seed_pass); - } - } - else if (method_name == "get_seed_phrase_info") - { - view::seed_info_param sip = AUTO_VAL_INIT(sip); - if (!epee::serialization::load_t_from_json(sip, params)) { view::api_response ar = AUTO_VAL_INIT(ar); - ar.error_code = "Wrong parameter"; + ar.error_code = "UNKNOWN METHOD"; res = sanitized_store_to_json(ar); } - else - { - view::api_response_t rsp = AUTO_VAL_INIT(rsp); - rsp.error_code = tools::get_seed_phrase_info(sip.seed_phrase, sip.seed_password, rsp.response_data); - res = sanitized_store_to_json(rsp); - } - } - else if (method_name == "invoke") - { - res = invoke(instance_id, params); + return res; } - else if (method_name == "get_wallet_status") - { - res = get_wallet_status(instance_id); - } - else if (method_name == "configure") - { - res = handle_configure(params); - } - else if (method_name == "reset_connection_url") - { - res = handle_reset_connection_url(params); - } - else if (method_name == "run_wallet") - { - res = handle_run_wallet(instance_id); - } - else if (method_name == "proxy_to_daemon") - { - res = handle_proxy_to_daemon(params); - } - else + catch (const std::exception& ex) { + LOG_ERROR("Exception during method call: " << method_name << ", instance id:" << instance_id << ", params: " << ENDL << params << ENDL << "exception text: " << ex.what()); view::api_response ar = AUTO_VAL_INIT(ar); - ar.error_code = "UNKNOWN METHOD"; + ar.error_code = std::string("EXCEPTION: ") + ex.what(); res = sanitized_store_to_json(ar); + return res; + } + catch (...) + { + LOG_ERROR("Unknown exception during method call: " << method_name << ", instance id:" << instance_id << ", params: " << ENDL << params); + view::api_response ar = AUTO_VAL_INIT(ar); + ar.error_code = "UNKONW_EXCEPTION"; + res = sanitized_store_to_json(ar); + return res; } - return res; } std::string try_pull_result(uint64_t job_id) @@ -805,16 +886,20 @@ namespace plain_wallet std::string get_wallet_info(hwallet h) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); wallet_extended_info wei = AUTO_VAL_INIT(wei); inst_ptr->gwm.get_wallet_info(h, wei.wi); inst_ptr->gwm.get_wallet_info_extra(h, wei.wi_extended); return sanitized_store_to_json(wei); + PLAIN_WALLET_CATCH(); } std::string reset_wallet_password(hwallet h, const std::string& password) { + PLAIN_WALLET_BEGIN_TRY_ENTRY(); GET_INSTANCE_PTR(inst_ptr); return inst_ptr->gwm.reset_wallet_password(h, password); + PLAIN_WALLET_CATCH(); } diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 8ecfad74..2524d688 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -1375,6 +1375,10 @@ std::string wallets_manager::close_wallet(size_t wallet_id) { return std::string(API_RETURN_CODE_FAIL) + ":" + e.what(); } + catch (...) + { + return API_RETURN_CODE_INTERNAL_ERROR; + } //m_pview->hide_wallet(); return API_RETURN_CODE_OK; }