Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Better error handling for push/send_transaction - develop #8998

Merged
merged 6 commits into from
Apr 27, 2020
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
59 changes: 48 additions & 11 deletions plugins/chain_api_plugin/chain_api_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ struct async_result_visitor : public fc::visitor<fc::variant> {
}
};

namespace {
template<typename T>
T parse_params(const std::string& body) {
if (body.empty()) {
EOS_THROW(chain::invalid_http_request, "A Request body is required");
}

try {
try {
return fc::json::from_string(body).as<T>();
} catch (const chain::chain_exception& e) { // EOS_RETHROW_EXCEPTIONS does not re-type these so, re-code it
throw fc::exception(e);
}
} EOS_RETHROW_EXCEPTIONS(chain::invalid_http_request, "Unable to parse valid input from POST body");
}
}

#define CALL(api_name, api_handle, api_namespace, call_name, http_response_code) \
{std::string("/v1/" #api_name "/" #call_name), \
[api_handle](string, string body, url_response_callback cb) mutable { \
Expand All @@ -44,23 +61,41 @@ struct async_result_visitor : public fc::visitor<fc::variant> {
} \
}}

#define CALL_WITH_400(api_name, api_handle, api_namespace, call_name, http_response_code) \
{std::string("/v1/" #api_name "/" #call_name), \
[api_handle](string, string body, url_response_callback cb) mutable { \
api_handle.validate(); \
try { \
auto params = parse_params<api_namespace::call_name ## _params>(body);\
fc::variant result( api_handle.call_name( std::move(params) ) ); \
cb(http_response_code, std::move(result)); \
} catch (...) { \
http_plugin::handle_exception(#api_name, #call_name, body, cb); \
} \
}}

#define CALL_ASYNC(api_name, api_handle, api_namespace, call_name, call_result, http_response_code) \
{std::string("/v1/" #api_name "/" #call_name), \
[api_handle](string, string body, url_response_callback cb) mutable { \
if (body.empty()) body = "{}"; \
api_handle.validate(); \
api_handle.call_name(fc::json::from_string(body).as<api_namespace::call_name ## _params>(),\
[cb, body](const fc::static_variant<fc::exception_ptr, call_result>& result){\
if (result.contains<fc::exception_ptr>()) {\
try {\
result.get<fc::exception_ptr>()->dynamic_rethrow_exception();\
} catch (...) {\
http_plugin::handle_exception(#api_name, #call_name, body, cb);\
try { \
auto params = parse_params<api_namespace::call_name ## _params>(body);\
api_handle.call_name( std::move(params),\
[cb, body](const fc::static_variant<fc::exception_ptr, call_result>& result){\
if (result.contains<fc::exception_ptr>()) {\
try {\
result.get<fc::exception_ptr>()->dynamic_rethrow_exception();\
} catch (...) {\
http_plugin::handle_exception(#api_name, #call_name, body, cb);\
}\
} else {\
cb(http_response_code, result.visit(async_result_visitor()));\
}\
} else {\
cb(http_response_code, result.visit(async_result_visitor()));\
}\
});\
});\
} catch (...) { \
http_plugin::handle_exception(#api_name, #call_name, body, cb); \
} \
}\
}

Expand All @@ -69,6 +104,8 @@ struct async_result_visitor : public fc::visitor<fc::variant> {
#define CHAIN_RO_CALL_ASYNC(call_name, call_result, http_response_code) CALL_ASYNC(chain, ro_api, chain_apis::read_only, call_name, call_result, http_response_code)
#define CHAIN_RW_CALL_ASYNC(call_name, call_result, http_response_code) CALL_ASYNC(chain, rw_api, chain_apis::read_write, call_name, call_result, http_response_code)

#define CHAIN_RO_CALL_WITH_400(call_name, http_response_code) CALL_WITH_400(chain, ro_api, chain_apis::read_only, call_name, http_response_code)

void chain_api_plugin::plugin_startup() {
ilog( "starting chain_api_plugin" );
my.reset(new chain_api_plugin_impl(app().get_plugin<chain_plugin>().chain()));
Expand Down
3 changes: 3 additions & 0 deletions plugins/http_plugin/http_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,9 @@ namespace eosio {
} catch (chain::unknown_block_exception& e) {
error_results results{400, "Unknown Block", error_results::error_info(e, verbose_http_errors)};
cb( 400, fc::variant( results ));
} catch (chain::invalid_http_request& e) {
error_results results{400, "Invalid Request", error_results::error_info(e, verbose_http_errors)};
cb( 400, fc::variant( results ));
} catch (chain::unsatisfied_authorization& e) {
error_results results{401, "UnAuthorized", error_results::error_info(e, verbose_http_errors)};
cb( 401, fc::variant( results ));
Expand Down