@@ -869,7 +869,15 @@ class SelectionVisitor
869869
870870 void visit (const peg::ast_node& selection);
871871
872- std::vector<std::pair<std::string_view, AwaitableResolver>> getValues ();
872+ struct VisitorValue
873+ {
874+ std::string_view name;
875+ std::optional<schema_location> location;
876+ std::optional<error_path> path;
877+ AwaitableResolver result;
878+ };
879+
880+ std::vector<VisitorValue> getValues ();
873881
874882private:
875883 void visitField (const peg::ast_node& field);
@@ -890,7 +898,7 @@ class SelectionVisitor
890898 std::shared_ptr<FragmentSpreadDirectiveStack> _fragmentSpreadDirectives;
891899 std::shared_ptr<FragmentSpreadDirectiveStack> _inlineFragmentDirectives;
892900 internal::string_view_set _names;
893- std::vector<std::pair<std::string_view, AwaitableResolver> > _values;
901+ std::vector<VisitorValue > _values;
894902};
895903
896904SelectionVisitor::SelectionVisitor (const SelectionSetParams& selectionSetParams,
@@ -924,7 +932,7 @@ SelectionVisitor::SelectionVisitor(const SelectionSetParams& selectionSetParams,
924932 _values.reserve (count);
925933}
926934
927- std::vector<std::pair<std::string_view, AwaitableResolver> > SelectionVisitor::getValues ()
935+ std::vector<SelectionVisitor::VisitorValue > SelectionVisitor::getValues ()
928936{
929937 auto values = std::move (_values);
930938
@@ -989,7 +997,7 @@ void SelectionVisitor::visitField(const peg::ast_node& field)
989997 { position.line , position.column },
990998 buildErrorPath (_path ? std::make_optional (_path->get ()) : std::nullopt ) } } }));
991999
992- _values.push_back ({ alias, promise.get_future () });
1000+ _values.push_back ({ alias, std:: nullopt , std:: nullopt , promise.get_future () });
9931001 return ;
9941002 }
9951003
@@ -1033,6 +1041,7 @@ void SelectionVisitor::visitField(const peg::ast_node& field)
10331041 std::make_optional (field_path { _path, path_segment { alias } }),
10341042 _launch,
10351043 };
1044+ const auto position = field.begin ();
10361045
10371046 try
10381047 {
@@ -1045,12 +1054,14 @@ void SelectionVisitor::visitField(const peg::ast_node& field)
10451054 _fragments,
10461055 _variables));
10471056
1048- _values.push_back ({ alias, std::move (result) });
1057+ _values.push_back ({ alias,
1058+ std::make_optional<schema_location>({ position.line , position.column }),
1059+ std::make_optional (buildErrorPath (selectionSetParams.errorPath )),
1060+ std::move (result) });
10491061 }
10501062 catch (schema_exception& scx)
10511063 {
10521064 std::promise<ResolverResult> promise;
1053- auto position = field.begin ();
10541065 auto messages = scx.getStructuredErrors ();
10551066
10561067 for (auto & message : messages)
@@ -1068,12 +1079,11 @@ void SelectionVisitor::visitField(const peg::ast_node& field)
10681079
10691080 promise.set_exception (std::make_exception_ptr (schema_exception { std::move (messages) }));
10701081
1071- _values.push_back ({ alias, promise.get_future () });
1082+ _values.push_back ({ alias, std:: nullopt , std:: nullopt , promise.get_future () });
10721083 }
10731084 catch (const std::exception& ex)
10741085 {
10751086 std::promise<ResolverResult> promise;
1076- auto position = field.begin ();
10771087 std::ostringstream message;
10781088
10791089 message << " Field error name: " << alias << " unknown error: " << ex.what ();
@@ -1083,7 +1093,7 @@ void SelectionVisitor::visitField(const peg::ast_node& field)
10831093 { position.line , position.column },
10841094 buildErrorPath (selectionSetParams.errorPath ) } } }));
10851095
1086- _values.push_back ({ alias, promise.get_future () });
1096+ _values.push_back ({ alias, std:: nullopt , std:: nullopt , promise.get_future () });
10871097 }
10881098}
10891099
@@ -1222,21 +1232,23 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams,
12221232
12231233 for (auto & child : children)
12241234 {
1225- auto name = child.first ;
1226-
12271235 try
12281236 {
12291237 co_await launch;
12301238
1231- auto value = co_await std::move ( child.second ) ;
1239+ auto value = co_await child.result ;
12321240
1233- if (!document.data .emplace_back (std::string { name }, std::move (value.data )))
1241+ if (!document.data .emplace_back (std::string { child. name }, std::move (value.data )))
12341242 {
12351243 std::ostringstream message;
12361244
1237- message << " Ambiguous field error name: " << name;
1245+ message << " Ambiguous field error name: " << child. name ;
12381246
1239- document.errors .push_back ({ message.str () });
1247+ auto location = (child.location ? schema_location { std::move (*child.location ) }
1248+ : schema_location {});
1249+ auto path = (child.path ? error_path { std::move (*child.path ) } : error_path {});
1250+
1251+ document.errors .push_back ({ message.str (), std::move (location), std::move (path) });
12401252 }
12411253
12421254 if (!value.errors .empty ())
@@ -1253,16 +1265,20 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams,
12531265 std::copy (errors.begin (), errors.end (), std::back_inserter (document.errors ));
12541266 }
12551267
1256- document.data .emplace_back (std::string { name }, {});
1268+ document.data .emplace_back (std::string { child. name }, {});
12571269 }
12581270 catch (const std::exception& ex)
12591271 {
12601272 std::ostringstream message;
12611273
1262- message << " Field error name: " << name << " unknown error: " << ex.what ();
1274+ message << " Field error name: " << child.name << " unknown error: " << ex.what ();
1275+
1276+ auto location = (child.location ? schema_location { std::move (*child.location ) }
1277+ : schema_location {});
1278+ auto path = (child.path ? error_path { std::move (*child.path ) } : error_path {});
12631279
1264- document.errors .push_back ({ message.str () });
1265- document.data .emplace_back (std::string { name }, {});
1280+ document.errors .push_back ({ message.str (), std::move (location), std::move (path) });
1281+ document.data .emplace_back (std::string { child. name }, {});
12661282 }
12671283 }
12681284
@@ -1454,8 +1470,8 @@ SubscriptionData::SubscriptionData(std::shared_ptr<OperationData> data, Subscrip
14541470{
14551471}
14561472
1457- // SubscriptionDefinitionVisitor visits the AST collects the fields referenced in the subscription
1458- // at the point where we create a subscription.
1473+ // SubscriptionDefinitionVisitor visits the AST collects the fields referenced in the
1474+ // subscription at the point where we create a subscription.
14591475class SubscriptionDefinitionVisitor
14601476{
14611477public:
@@ -1680,9 +1696,9 @@ Request::Request(TypeMap operationTypes, std::shared_ptr<schema::Schema> schema)
16801696
16811697Request::~Request ()
16821698{
1683- // The default implementation is fine, but it can't be declared as = default because it needs to
1684- // know how to destroy the _validation member and it can't do that with just a forward
1685- // declaration of the class.
1699+ // The default implementation is fine, but it can't be declared as = default because it
1700+ // needs to know how to destroy the _validation member and it can't do that with just a
1701+ // forward declaration of the class.
16861702}
16871703
16881704std::list<schema_error> Request::validate (peg::ast& query) const
@@ -1835,8 +1851,8 @@ AwaitableSubscribe Request::subscribe(RequestSubscribeParams params)
18351851
18361852 if (itrOperation == _operations.end ())
18371853 {
1838- // There may be an empty entry in the operations map, but if it's completely missing then
1839- // that means the schema doesn't support subscriptions at all.
1854+ // There may be an empty entry in the operations map, but if it's completely missing
1855+ // then that means the schema doesn't support subscriptions at all.
18401856 throw std::logic_error (" Subscriptions not supported" );
18411857 }
18421858
@@ -1897,8 +1913,8 @@ AwaitableUnsubscribe Request::unsubscribe(RequestUnsubscribeParams params)
18971913
18981914 if (itrOperation == _operations.end ())
18991915 {
1900- // There may be an empty entry in the operations map, but if it's completely missing then
1901- // that means the schema doesn't support subscriptions at all.
1916+ // There may be an empty entry in the operations map, but if it's completely missing
1917+ // then that means the schema doesn't support subscriptions at all.
19021918 throw std::logic_error (" Subscriptions not supported" );
19031919 }
19041920
@@ -1948,8 +1964,8 @@ AwaitableDeliver Request::deliver(RequestDeliverParams params) const
19481964
19491965 if (itrOperation == _operations.end ())
19501966 {
1951- // There may be an empty entry in the operations map, but if it's completely missing then
1952- // that means the schema doesn't support subscriptions at all.
1967+ // There may be an empty entry in the operations map, but if it's completely missing
1968+ // then that means the schema doesn't support subscriptions at all.
19531969 throw std::logic_error (" Subscriptions not supported" );
19541970 }
19551971
@@ -2211,8 +2227,8 @@ std::vector<std::shared_ptr<const SubscriptionData>> Request::collectRegistratio
22112227 const auto & subscriptionArguments = registration->arguments ;
22122228 bool matchedArguments = true ;
22132229
2214- // If the field in this subscription had arguments that did not match what was
2215- // provided in this event, don't deliver the event to this subscription
2230+ // If the field in this subscription had arguments that did not match what
2231+ // was provided in this event, don't deliver the event to this subscription
22162232 for (const auto & required : subscriptionArguments)
22172233 {
22182234 if (!(*argumentsMatch)(required))
@@ -2231,7 +2247,8 @@ std::vector<std::shared_ptr<const SubscriptionData>> Request::collectRegistratio
22312247 if (directivesMatch)
22322248 {
22332249 // If the field in this subscription had field directives that did not match
2234- // what was provided in this event, don't deliver the event to this subscription
2250+ // what was provided in this event, don't deliver the event to this
2251+ // subscription
22352252 const auto & subscriptionFieldDirectives = registration->fieldDirectives ;
22362253 bool matchedFieldDirectives = true ;
22372254
0 commit comments