Skip to content

Commit

Permalink
Merge pull request #285 from wravery/improve-awaitable-errors
Browse files Browse the repository at this point in the history
Improve awaitable errors
  • Loading branch information
wravery committed May 11, 2023
2 parents 31b3312 + f170836 commit ed0a754
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 47 deletions.
80 changes: 75 additions & 5 deletions samples/proxy/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Query
explicit Query(std::string_view host, std::string_view port, std::string_view target,
int version) noexcept;

std::future<std::string> getRelay(std::string&& queryArg,
std::future<std::optional<std::string>> getRelay(std::string&& queryArg,
std::optional<std::string>&& operationNameArg,
std::optional<std::string>&& variablesArg) const;

Expand All @@ -73,7 +73,7 @@ Query::Query(

// Based on:
// https://www.boost.org/doc/libs/1_82_0/libs/beast/example/http/client/awaitable/http_client_awaitable.cpp
std::future<std::string> Query::getRelay(std::string&& queryArg,
std::future<std::optional<std::string>> Query::getRelay(std::string&& queryArg,
std::optional<std::string>&& operationNameArg, std::optional<std::string>&& variablesArg) const
{
response::Value payload { response::Type::Map };
Expand All @@ -99,7 +99,7 @@ std::future<std::string> Query::getRelay(std::string&& queryArg,
const char* port,
const char* target,
int version,
std::string requestBody) -> net::awaitable<std::string> {
std::string requestBody) -> net::awaitable<std::optional<std::string>> {
// These objects perform our I/O. They use an executor with a default completion token
// of use_awaitable. This makes our code easy, but will use exceptions as the default
// error handling, i.e. if the connection drops, we might see an exception.
Expand Down Expand Up @@ -150,7 +150,7 @@ std::future<std::string> Query::getRelay(std::string&& queryArg,
throw boost::system::system_error(ec, "shutdown");
}

co_return std::string { std::move(res.body()) };
co_return std::make_optional<std::string>(std::move(res.body()));
}(m_host.c_str(), m_port.c_str(), m_target.c_str(), m_version, std::move(requestBody)),
net::use_future);

Expand Down Expand Up @@ -182,8 +182,78 @@ int main(int argc, char** argv)
auto serviceResponse = client::parseServiceResponse(
service->resolve({ query, GetOperationName(), std::move(variables), launch }).get());
auto result = client::query::relayQuery::parseResponse(std::move(serviceResponse.data));
auto errors = std::move(serviceResponse.errors);

std::cout << result.relay << std::endl;
if (result.relay)
{
std::cout << *result.relay << std::endl;
}

if (!errors.empty())
{
std::cerr << "Errors executing query:" << std::endl << GetRequestText() << std::endl;

for (const auto& error : errors)
{
std::cerr << "Error: " << error.message;

if (!error.locations.empty())
{
bool firstLocation = true;

std::cerr << ", Locations: [";

for (const auto& location : error.locations)
{
if (!firstLocation)
{
std::cerr << ", ";
}

firstLocation = false;

std::cerr << "(line: " << location.line << ", column: " << location.column
<< ")";
}

std::cerr << "]";
}

if (!error.path.empty())
{
bool firstSegment = true;

std::cerr << ", Path: ";

for (const auto& segment : error.path)
{
std::visit(
[firstSegment](const auto& value) noexcept {
using _Type = std::decay_t<decltype(value)>;

if constexpr (std::is_same_v<std::string, _Type>)
{
if (!firstSegment)
{
std::cerr << "/";
}

std::cerr << value;
}
else if constexpr (std::is_same_v<int, _Type>)
{
std::cerr << "[" << value << "]";
}
},
segment);

firstSegment = false;
}
}

std::cerr << std::endl;
}
}
}
catch (const std::runtime_error& ex)
{
Expand Down
2 changes: 1 addition & 1 deletion samples/proxy/query/ProxyClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Response parseResponse(response::Value&& response)
{
if (member.first == R"js(relay)js"sv)
{
result.relay = ModifiedResponse<std::string>::parse(std::move(member.second));
result.relay = ModifiedResponse<std::string>::parse<TypeModifier::Nullable>(std::move(member.second));
continue;
}
}
Expand Down
2 changes: 1 addition & 1 deletion samples/proxy/query/ProxyClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct [[nodiscard]] Variables

struct [[nodiscard]] Response
{
std::string relay {};
std::optional<std::string> relay {};
};

[[nodiscard]] Response parseResponse(response::Value&& response);
Expand Down
4 changes: 2 additions & 2 deletions samples/proxy/schema/QueryObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ service::AwaitableResolver Query::resolveRelay(service::ResolverParams&& params)
auto result = _pimpl->getRelay(service::FieldParams(service::SelectionSetParams{ params }, std::move(directives)), std::move(argQuery), std::move(argOperationName), std::move(argVariables));
resolverLock.unlock();

return service::ModifiedResult<std::string>::convert(std::move(result), std::move(params));
return service::ModifiedResult<std::string>::convert<service::TypeModifier::Nullable>(std::move(result), std::move(params));
}

service::AwaitableResolver Query::resolve_typename(service::ResolverParams&& params) const
Expand All @@ -92,7 +92,7 @@ service::AwaitableResolver Query::resolve_type(service::ResolverParams&& params)
void AddQueryDetails(const std::shared_ptr<schema::ObjectType>& typeQuery, const std::shared_ptr<schema::Schema>& schema)
{
typeQuery->AddFields({
schema::Field::Make(R"gql(relay)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(String)gql"sv)), {
schema::Field::Make(R"gql(relay)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv), {
schema::InputValue::Make(R"gql(query)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(String)gql"sv)), R"gql()gql"sv),
schema::InputValue::Make(R"gql(operationName)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv),
schema::InputValue::Make(R"gql(variables)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv)
Expand Down
8 changes: 4 additions & 4 deletions samples/proxy/schema/QueryObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ namespace methods::QueryHas {
template <class TImpl>
concept getRelayWithParams = requires (TImpl impl, service::FieldParams params, std::string queryArg, std::optional<std::string> operationNameArg, std::optional<std::string> variablesArg)
{
{ service::AwaitableScalar<std::string> { impl.getRelay(std::move(params), std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } };
{ service::AwaitableScalar<std::optional<std::string>> { impl.getRelay(std::move(params), std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } };
};

template <class TImpl>
concept getRelay = requires (TImpl impl, std::string queryArg, std::optional<std::string> operationNameArg, std::optional<std::string> variablesArg)
{
{ service::AwaitableScalar<std::string> { impl.getRelay(std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } };
{ service::AwaitableScalar<std::optional<std::string>> { impl.getRelay(std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } };
};

template <class TImpl>
Expand Down Expand Up @@ -58,7 +58,7 @@ class [[nodiscard]] Query final
virtual void beginSelectionSet(const service::SelectionSetParams& params) const = 0;
virtual void endSelectionSet(const service::SelectionSetParams& params) const = 0;

[[nodiscard]] virtual service::AwaitableScalar<std::string> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional<std::string>&& operationNameArg, std::optional<std::string>&& variablesArg) const = 0;
[[nodiscard]] virtual service::AwaitableScalar<std::optional<std::string>> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional<std::string>&& operationNameArg, std::optional<std::string>&& variablesArg) const = 0;
};

template <class T>
Expand All @@ -70,7 +70,7 @@ class [[nodiscard]] Query final
{
}

[[nodiscard]] service::AwaitableScalar<std::string> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional<std::string>&& operationNameArg, std::optional<std::string>&& variablesArg) const final
[[nodiscard]] service::AwaitableScalar<std::optional<std::string>> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional<std::string>&& operationNameArg, std::optional<std::string>&& variablesArg) const final
{
if constexpr (methods::QueryHas::getRelayWithParams<T>)
{
Expand Down
2 changes: 1 addition & 1 deletion samples/proxy/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
# Licensed under the MIT License.

type Query {
relay(query: String!, operationName: String, variables: String): String!
relay(query: String!, operationName: String, variables: String): String
}
Loading

0 comments on commit ed0a754

Please sign in to comment.