Improve the error reporting in HTTP client sample
This commit is contained in:
Родитель
31b3312b2d
Коммит
81a3854c2a
|
@ -51,7 +51,7 @@ public:
|
|||
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;
|
||||
|
||||
|
@ -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 };
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ struct [[nodiscard]] Variables
|
|||
|
||||
struct [[nodiscard]] Response
|
||||
{
|
||||
std::string relay {};
|
||||
std::optional<std::string> relay {};
|
||||
};
|
||||
|
||||
[[nodiscard]] Response parseResponse(response::Value&& response);
|
||||
|
|
|
@ -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
|
||||
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
@ -58,7 +58,7 @@ private:
|
|||
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>
|
||||
|
@ -70,7 +70,7 @@ private:
|
|||
{
|
||||
}
|
||||
|
||||
[[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>)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче