ChilliCream / ChilliCream/graphql-platform
Subgraph transport exception for fields below an entity cause entire entity to be nulled
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 5.8k
- Forks
- 810
- Avg merge
- 15h 39m
- Merged PRs (30d)
- 98
Description
Is there an existing issue for this?
- I have searched the existing issues
Product
Hot Chocolate
Describe the bug
If two or more subgraphs expose an entity via a top-level resolver like productById and one of the subgraphs fails to provide their part of the entity, the entire entity resolver result is nulled, even if the top-most fields below Product requested from the faulty subgraph are nullable.
For a query like this:
query Product {
productById(id: "UHJvZHVjdAppMQ==") {
# Subgraph: Product
name
# Subgraph: Reviews
reviews { # nullable
body
}
}
}
My expectation would be a response like this, if the reviews Subgraph can not be reached:
{
"errors": [
// Errors for each top-most field that couldn't be resolved from the subgraph
//(in this case just `reviews`)
],
"data": {
"productById":{
"name": "iPhone",
"reviews": null
}
}
}
The actual result you'd get is:
{
"errors": [
{
"message": "Internal Execution Error"
}
],
"data": {
"productById": null
}
}
This is pretty bad, since a single field being requested from a faulty subgraph could take down an entire page!
The behavior for top-level query fields being resolved from different subgraphs is already correct.
Steps to reproduce
I've created an integration test showcasing this:
[Fact]
public async Task Test()
{
// arrange
using var demoProject = await DemoProject.CreateAsync();
var fusionGraph = await new FusionGraphComposer(logFactory: _logFactory).ComposeAsync(
new[]
{
demoProject.Products.ToConfiguration(ProductsExtensionSdl),
demoProject.Reviews.ToConfiguration(ReviewsExtensionSdl),
},
new FusionFeatureCollection(FusionFeatures.NodeField));
var executor = await new ServiceCollection()
.AddSingleton(demoProject.HttpClientFactory)
.AddSingleton(demoProject.WebSocketConnectionFactory)
.AddSingleton<IConfigurationRewriter, CustomRewriter>()
.AddFusionGatewayServer()
.ConfigureFromDocument(SchemaFormatter.FormatAsDocument(fusionGraph))
.BuildRequestExecutorAsync();
var request = Parse(
"""
query Product {
productById(id: "UHJvZHVjdAppMQ==") {
# Subgraph: Product
name
# Subgraph: Reviews
reviews {
body
}
}
}
""");
// act
await using var result = await executor.ExecuteAsync(
QueryRequestBuilder
.New()
.SetQuery(request)
.Create());
// assert
var snapshot = new Snapshot();
CollectSnapshotData(snapshot, request, result, fusionGraph);
await snapshot.MatchAsync();
Assert.Null(result.ExpectQueryResult().Errors);
}
private class CustomRewriter : ConfigurationRewriter
{
protected override ValueTask<Metadata.HttpClientConfiguration> RewriteAsync(
Metadata.HttpClientConfiguration configuration,
CancellationToken cancellationToken)
{
if (configuration.ClientName == "Reviews")
{
// This simulates the Reviews subgraph not being reachable
return base.RewriteAsync(
configuration with { EndpointUri = new Uri("http://client") },
cancellationToken);
}
return base.RewriteAsync(configuration, cancellationToken);
}
}
Relevant log output
No response
Additional Context?
No response
Version
14.0.0-p.15
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the integration test in the issue, including FusionGraphComposer, AddFusionGatewayServer, and CustomRewriter, and run it against the failing Reviews-subgraph scenario. Inspect the execution path for entity fields below productById. Done means the snapshot shows productById and name preserved, reviews set to null, and errors limited to the failed top-level field.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, graphql
- Domain
- api, backend, distributed-systems, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100