in src/GraphQLService.cpp [966:1104]
void SelectionVisitor::visitField(const peg::ast_node& field)
{
	std::string_view name;
	peg::on_first_child<peg::field_name>(field, [&name](const peg::ast_node& child) {
		name = child.string_view();
	});
	std::string_view alias;
	peg::on_first_child<peg::alias_name>(field, [&alias](const peg::ast_node& child) {
		alias = child.string_view();
	});
	if (alias.empty())
	{
		alias = name;
	}
	if (!_names.emplace(alias).second)
	{
		// Skip resolving fields which map to the same response name as a field we've already
		// resolved. Validation should handle merging multiple references to the same field or
		// to compatible fields.
		return;
	}
	const auto itrResolver = _resolvers.find(name);
	if (itrResolver == _resolvers.end())
	{
		std::promise<ResolverResult> promise;
		auto position = field.begin();
		std::ostringstream error;
		error << "Unknown field name: " << name;
		promise.set_exception(
			std::make_exception_ptr(schema_exception { { schema_error { error.str(),
				{ position.line, position.column },
				buildErrorPath(_path ? std::make_optional(_path->get()) : std::nullopt) } } }));
		_values.push_back({ alias, promise.get_future() });
		return;
	}
	DirectiveVisitor directiveVisitor(_variables);
	peg::on_first_child<peg::directives>(field, [&directiveVisitor](const peg::ast_node& child) {
		directiveVisitor.visit(child);
	});
	if (directiveVisitor.shouldSkip())
	{
		return;
	}
	response::Value arguments(response::Type::Map);
	peg::on_first_child<peg::arguments>(field, [this, &arguments](const peg::ast_node& child) {
		ValueVisitor visitor(_variables);
		for (auto& argument : child.children)
		{
			visitor.visit(*argument->children.back());
			arguments.emplace_back(argument->children.front()->string(), visitor.getValue());
		}
	});
	const peg::ast_node* selection = nullptr;
	peg::on_first_child<peg::selection_set>(field, [&selection](const peg::ast_node& child) {
		selection = &child;
	});
	const SelectionSetParams selectionSetParams {
		_resolverContext,
		_state,
		_operationDirectives,
		_fragmentDefinitionDirectives,
		_fragmentSpreadDirectives,
		_inlineFragmentDirectives,
		std::make_optional(field_path { _path, path_segment { alias } }),
		_launch,
	};
	try
	{
		auto result = itrResolver->second(ResolverParams(selectionSetParams,
			field,
			std::string(alias),
			std::move(arguments),
			directiveVisitor.getDirectives(),
			selection,
			_fragments,
			_variables));
		_values.push_back({ alias, std::move(result) });
	}
	catch (schema_exception& scx)
	{
		std::promise<ResolverResult> promise;
		auto position = field.begin();
		auto messages = scx.getStructuredErrors();
		for (auto& message : messages)
		{
			if (message.location.line == 0)
			{
				message.location = { position.line, position.column };
			}
			if (message.path.empty())
			{
				message.path = buildErrorPath(selectionSetParams.errorPath);
			}
		}
		promise.set_exception(std::make_exception_ptr(schema_exception { std::move(messages) }));
		_values.push_back({ alias, promise.get_future() });
	}
	catch (const std::exception& ex)
	{
		std::promise<ResolverResult> promise;
		auto position = field.begin();
		std::ostringstream message;
		message << "Field error name: " << alias << " unknown error: " << ex.what();
		promise.set_exception(
			std::make_exception_ptr(schema_exception { { schema_error { message.str(),
				{ position.line, position.column },
				buildErrorPath(selectionSetParams.errorPath) } } }));
		_values.push_back({ alias, promise.get_future() });
	}
}