Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

Query Error Responses #1770

Merged
merged 12 commits into from
Oct 17, 2018
Merged

Query Error Responses #1770

merged 12 commits into from
Oct 17, 2018

Conversation

Akvinikym
Copy link
Contributor

Description of the Change

Introducing stateful error query responses.

Benefits

Users will see, why their queries fail.

Possible Drawbacks

None.

Signed-off-by: Akvinikym <anarant12@gmail.com>
Signed-off-by: Akvinikym <anarant12@gmail.com>
Signed-off-by: Akvinikym <anarant12@gmail.com>
Signed-off-by: Akvinikym <anarant12@gmail.com>
return *static_cast<shared_model::proto::Transaction *>(
clone(tx).get());
});
boost::transform(range_gen(boost::size(block->transactions()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe move out the range creation so the code is more readable?


/**
* Execute query in F and return builder result from B
* Execute query in F and return query response from B
* Q is query tuple, P is permission tuple
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe name Q a QueryTuple instead? Same for the PermissionTuple

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am always for giving template parameters meaningful names :)

using T = concat<Q, P>;
try {
soci::rowset<T> st = std::forward<F>(f)();
auto range = boost::make_iterator_range(st.begin(), st.end());

return apply(
viewPermissions<P>(range.front()), [range, &b](auto... perms) {
viewPermissions<P>(range.front()),
[this, range, &b, err_response = std::move(err_response)](
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since err_response is a universal reference, better to forward it?

return query_response_factory_
->createErrorQueryResponse(
QueryErrorType::kStatefulFailed,
"could not create asset object: " + err.error,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same error is duplicated for log and here, please move it to a common variable.

Signed-off-by: Akvinikym <anarant12@gmail.com>
Signed-off-by: Akvinikym <anarant12@gmail.com>
#include "common/types.hpp"
#include "cryptography/public_key.hpp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this include needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's used in line 411:
return shared_model::interface::types::PubkeyType{ shared_model::crypto::Blob::fromHexString(public_key)};

RangeGen &&range_gen,
Pred &&pred) {
std::vector<std::unique_ptr<shared_model::interface::Transaction>>
result{};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary {}

return stateful_failed;
return query_response_factory_->createErrorQueryResponse(
QueryErrorType::kStatefulFailed,
"failed to execute query: " + std::string(e.what()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replication of strings. Also you seem to log some errors, but not others. Is this intentional?
If you want to log all errors you can wrap logging and error construction in a function to reduce code duplication.

log_(logger::log("PostgresQueryExecutorVisitor")) {}

void PostgresQueryExecutorVisitor::setCreatorId(
const shared_model::interface::types::AccountIdType &creator_id) {
creator_id_ = creator_id;
}

QueryResponseBuilderDone PostgresQueryExecutorVisitor::operator()(
void PostgresQueryExecutorVisitor::setQueryHash(
const shared_model::crypto::Hash &query_hash) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use shared_model::interface::types::HashType, so that you do not depend on cryptography directly

@l4l
Copy link
Contributor

l4l commented Oct 13, 2018

Please update your branch and make sure that CI become green

@l4l l4l added needs-correction pr/rfc is not completed and might be updated ametsuchi labels Oct 13, 2018
Signed-off-by: Akvinikym <anarant12@gmail.com>
return logAndReturnErrorResponse(
QueryErrorType::kStatefulFailed,
err_response(),
this->query_hash_,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You pass three parameters which are class members. Maybe make logAndReturnErrorResponse a member of executor, so you do not need to pass parameters each time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is used in both PostgresQueryExecutorVisitor and PostgresQueryExecutor, thus making it member will force having two identical function definitions

@l4l l4l added needs-review pr awaits review from maintainers and removed needs-correction pr/rfc is not completed and might be updated labels Oct 15, 2018
* @tparam QueryExecutor - function, which executes the query
* @tparam ResponseCreator - function, which creates response of the query
* @tparam ErrResponse - function, which creates error response
* @param query_executor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe parameters and return, or make a description without detailed descriptions with @.

iroha::ametsuchi::QueryErrorType error_type,
std::string error_body,
const shared_model::crypto::Hash &query_hash,
std::shared_ptr<shared_model::interface::QueryResponseFactory>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not need shared ownership of QueryResponseFactory. Const reference can be used instead


std::string error;
switch (error_type) {
case QueryErrorType::kNoAccount: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code block should not be required in case

QueryErrorType::kNoAccount, std::move(error), query_hash);
}
case QueryErrorType::kNoSignatories: {
error = "no signatories found in account with such id: " + error_body;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making a lambda function, since each case looks almost identical. For example:

return make_error("no signatories found in account with such id: " + error_body, 
                  QueryErrorType::kNoSignatories);

This lambda can capture query_hash, and other necessary variables.

return *static_cast<shared_model::proto::Transaction *>(
clone(tx).get());
});
auto filtered_txs = range_gen(boost::size(block->transactions()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There were some issues with ranges when such assignment was made. Please make sure that Linux CI passes.

[this,
range,
&response_creator,
err_response =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&err_response should suffice here.

return stateful_failed;
return logAndReturnErrorResponse(
QueryErrorType::kStatefulFailed,
err_response(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, it is required to use forward here since there could be &- and &&-modified methods.

return logAndReturnErrorResponse(
QueryErrorType::kStatefulFailed,
std::move(e.error),
this->query_hash_,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be moved to member method:

auto PostgresQueryExecutorVisitor::makeErrorResponse(Type type, Error error) {
  return logAndReturnErrorResponse(type, error, query_hash_, query_response_factory_, log_);
}

Duplication in PostgresQueryExecutor may not be as bad.

shared_model::proto::AccountAsset *>(
v.value.get());
account_assets.push_back(proto);
account_assets.push_back(clone(*v.value.get()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to avoid clone here?


soci::session &sql_;
KeyValueStorage &block_store_;
shared_model::interface::types::AccountIdType creator_id_;
std::shared_ptr<shared_model::interface::CommonObjectsFactory> factory_;
shared_model::crypto::Hash query_hash_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> HashType?

Signed-off-by: Akvinikym <anarant12@gmail.com>
Signed-off-by: Akvinikym <anarant12@gmail.com>
@l4l
Copy link
Contributor

l4l commented Oct 16, 2018

Roses are red,
Violets are blue
and red CI saddens you

Signed-off-by: Akvinikym <anarant12@gmail.com>
this->query_hash_,
query_response_factory_,
log_);
std::forward<std::string>(err_response()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be std::forward<ErrResponse>(err_response)(), since return type is std::string value anyway, but err_response can be reference or value.

Signed-off-by: Akvinikym <anarant12@gmail.com>
@Akvinikym Akvinikym merged commit 497f520 into dev Oct 17, 2018
@Akvinikym Akvinikym deleted the feature/qry-err-rsp branch October 17, 2018 09:18
@l4l l4l removed the needs-review pr awaits review from maintainers label Oct 17, 2018
bakhtin pushed a commit that referenced this pull request Nov 2, 2018
Signed-off-by: Akvinikym <anarant12@gmail.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

Successfully merging this pull request may close these issues.

None yet

4 participants