diff --git a/src/HotChocolate/Adapters/src/Adapters.OpenApi.Core/Execution/DynamicEndpointMiddleware.cs b/src/HotChocolate/Adapters/src/Adapters.OpenApi.Core/Execution/DynamicEndpointMiddleware.cs
index 436c6b24970..3852f7b89db 100644
--- a/src/HotChocolate/Adapters/src/Adapters.OpenApi.Core/Execution/DynamicEndpointMiddleware.cs
+++ b/src/HotChocolate/Adapters/src/Adapters.OpenApi.Core/Execution/DynamicEndpointMiddleware.cs
@@ -69,7 +69,7 @@ await Results.Problem(
var requestBuilder = OperationRequestBuilder.New()
.SetDocument(endpointDescriptor.Document)
- .SetErrorHandlingMode(ErrorHandlingMode.Halt)
+ .SetErrorHandlingMode(ErrorHandlingMode.Propagate)
.SetVariableValues(variables);
await session.OnCreateAsync(context, requestBuilder, cancellationToken);
diff --git a/src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Parsers/DefaultHttpRequestParser.cs b/src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Parsers/DefaultHttpRequestParser.cs
index d0fc737cd0b..8045ae8d2fe 100644
--- a/src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Parsers/DefaultHttpRequestParser.cs
+++ b/src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Parsers/DefaultHttpRequestParser.cs
@@ -228,11 +228,7 @@ public GraphQLRequest ParseRequestFromParams(IQueryCollection parameters)
extensions = JsonDocument.Parse(se);
}
- ErrorHandlingMode? errorHandlingMode = null;
- if (!string.IsNullOrEmpty(onError))
- {
- errorHandlingMode = ParseErrorHandlingMode(onError);
- }
+ var errorHandlingMode = ParseErrorHandlingMode(onError);
return new GraphQLRequest(
document,
@@ -327,8 +323,13 @@ public GraphQLRequest ParsePersistedOperationRequestFromParams(
return (documentHash, document);
}
- private static ErrorHandlingMode? ParseErrorHandlingMode(string onError)
+ private static ErrorHandlingMode? ParseErrorHandlingMode(string? onError)
{
+ if (string.IsNullOrEmpty(onError))
+ {
+ return null;
+ }
+
if (onError.Equals("PROPAGATE", StringComparison.OrdinalIgnoreCase))
{
return ErrorHandlingMode.Propagate;
@@ -339,12 +340,8 @@ public GraphQLRequest ParsePersistedOperationRequestFromParams(
return ErrorHandlingMode.Null;
}
- if (onError.Equals("HALT", StringComparison.OrdinalIgnoreCase))
- {
- return ErrorHandlingMode.Halt;
- }
-
- return null;
+ throw new InvalidGraphQLRequestException(
+ $"Unknown 'onError' value '{onError}'. Allowed values are 'PROPAGATE' or 'NULL'.");
}
public GraphQLRequest[] ParseRequest(string sourceText)
diff --git a/src/HotChocolate/AspNetCore/src/Transport.Abstractions/Serialization/Utf8JsonWriterHelper.cs b/src/HotChocolate/AspNetCore/src/Transport.Abstractions/Serialization/Utf8JsonWriterHelper.cs
index 7f4481f21ec..7429617310c 100644
--- a/src/HotChocolate/AspNetCore/src/Transport.Abstractions/Serialization/Utf8JsonWriterHelper.cs
+++ b/src/HotChocolate/AspNetCore/src/Transport.Abstractions/Serialization/Utf8JsonWriterHelper.cs
@@ -728,7 +728,6 @@ private static string GetErrorHandlingModeAsString(ErrorHandlingMode mode)
{
ErrorHandlingMode.Propagate => "PROPAGATE",
ErrorHandlingMode.Null => "NULL",
- ErrorHandlingMode.Halt => "HALT",
_ => throw new ArgumentOutOfRangeException(nameof(mode))
};
}
diff --git a/src/HotChocolate/AspNetCore/src/Transport.Http/DefaultGraphQLHttpClient.cs b/src/HotChocolate/AspNetCore/src/Transport.Http/DefaultGraphQLHttpClient.cs
index 049d6020b0c..a52f23dad45 100644
--- a/src/HotChocolate/AspNetCore/src/Transport.Http/DefaultGraphQLHttpClient.cs
+++ b/src/HotChocolate/AspNetCore/src/Transport.Http/DefaultGraphQLHttpClient.cs
@@ -599,7 +599,6 @@ private static string GetErrorHandlingModeAsString(ErrorHandlingMode mode)
{
ErrorHandlingMode.Propagate => "PROPAGATE",
ErrorHandlingMode.Null => "NULL",
- ErrorHandlingMode.Halt => "HALT",
_ => throw new ArgumentOutOfRangeException(nameof(mode))
};
}
diff --git a/src/HotChocolate/AspNetCore/test/AspNetCore.Tests/GraphQLOverHttpSpecTests.cs b/src/HotChocolate/AspNetCore/test/AspNetCore.Tests/GraphQLOverHttpSpecTests.cs
index b6889e150e3..79c15941fd3 100644
--- a/src/HotChocolate/AspNetCore/test/AspNetCore.Tests/GraphQLOverHttpSpecTests.cs
+++ b/src/HotChocolate/AspNetCore/test/AspNetCore.Tests/GraphQLOverHttpSpecTests.cs
@@ -540,6 +540,27 @@ public async Task After_Execution_StatusCode_Is_200()
Assert.Equal(OK, response.StatusCode);
}
+ [Fact]
+ public async Task Unknown_OnError_Value_Returns_BadRequest()
+ {
+ // arrange
+ var client = GetClient(Latest);
+
+ // act
+ using var request = new HttpRequestMessage(HttpMethod.Post, s_url);
+ request.Content = new StringContent(
+ """{"query":"{ __typename }","onError":"HALT"}""",
+ System.Text.Encoding.UTF8,
+ "application/json");
+
+ using var response = await client.SendAsync(request);
+
+ // assert
+ Assert.Equal(BadRequest, response.StatusCode);
+ var body = await response.Content.ReadAsStringAsync();
+ Assert.Contains("onError", body, StringComparison.OrdinalIgnoreCase);
+ }
+
private HttpClient GetClient(HttpTransportVersion serverTransportVersion)
{
var server = CreateStarWarsServer(
diff --git a/src/HotChocolate/AspNetCore/test/Transport.Http.Tests/GraphQLHttpClientTests.cs b/src/HotChocolate/AspNetCore/test/Transport.Http.Tests/GraphQLHttpClientTests.cs
index bb390f535e8..4a137764c3d 100644
--- a/src/HotChocolate/AspNetCore/test/Transport.Http.Tests/GraphQLHttpClientTests.cs
+++ b/src/HotChocolate/AspNetCore/test/Transport.Http.Tests/GraphQLHttpClientTests.cs
@@ -442,7 +442,7 @@ public async Task Post_GraphQL_Query_With_OnError()
// act
var response = await client.PostAsync(
- new OperationRequest(query, onError: ErrorHandlingMode.Halt),
+ new OperationRequest(query, onError: ErrorHandlingMode.Null),
cts.Token);
// assert
@@ -451,7 +451,7 @@ public async Task Post_GraphQL_Query_With_OnError()
"""
{
"data": {
- "errorHandlingMode": "HALT"
+ "errorHandlingMode": "NULL"
}
}
""");
@@ -766,7 +766,7 @@ public async Task Get_GraphQL_Query_With_OnError()
// act
var response = await client.GetAsync(
- new OperationRequest(query, onError: ErrorHandlingMode.Halt),
+ new OperationRequest(query, onError: ErrorHandlingMode.Null),
cts.Token);
// assert
@@ -775,7 +775,7 @@ public async Task Get_GraphQL_Query_With_OnError()
"""
{
"data": {
- "errorHandlingMode": "HALT"
+ "errorHandlingMode": "NULL"
}
}
""");
diff --git a/src/HotChocolate/Core/src/Types/Execution/Processing/OperationContext.Pooling.cs b/src/HotChocolate/Core/src/Types/Execution/Processing/OperationContext.Pooling.cs
index a2929367ce9..de16c1a4d9b 100644
--- a/src/HotChocolate/Core/src/Types/Execution/Processing/OperationContext.Pooling.cs
+++ b/src/HotChocolate/Core/src/Types/Execution/Processing/OperationContext.Pooling.cs
@@ -39,6 +39,7 @@ internal sealed partial class OperationContext
private int _branchId;
private int _variableIndex;
private object? _rootValue;
+ private bool _propagateNullValues;
private bool _isInitialized;
public OperationContext(
@@ -87,6 +88,10 @@ public void Initialize(
_batchDispatcher = batchDispatcher;
_variableIndex = variableIndex;
+ var errorHandlingMode = _requestContext.Request.ErrorHandlingMode
+ ?? _schema.GetOptions().DefaultErrorHandlingMode;
+ _propagateNullValues = errorHandlingMode is Language.ErrorHandlingMode.Propagate;
+
IncludeFlags = operation.CreateIncludeFlags(variables);
DeferFlags = operation.CreateDeferFlags(variables);
Result.Data = new ResultDocument(operation, IncludeFlags);
@@ -128,6 +133,7 @@ public void InitializeDeferContext(
_currentBranchTracker = context._currentBranchTracker;
_currentWorkScheduler = context._currentWorkScheduler;
_currentDeferExecutionCoordinator = context._currentDeferExecutionCoordinator;
+ _propagateNullValues = context._propagateNullValues;
_branchId = executionBranchId;
_isInitialized = true;
@@ -178,6 +184,7 @@ public void Clean()
_resolveQueryRootValue = null!;
_batchDispatcher = null!;
_branchId = int.MinValue;
+ _propagateNullValues = false;
_isInitialized = false;
Result.Reset();
}
diff --git a/src/HotChocolate/Core/src/Types/Execution/Processing/OperationContext.cs b/src/HotChocolate/Core/src/Types/Execution/Processing/OperationContext.cs
index e912a4dc5bd..d7021e849cc 100644
--- a/src/HotChocolate/Core/src/Types/Execution/Processing/OperationContext.cs
+++ b/src/HotChocolate/Core/src/Types/Execution/Processing/OperationContext.cs
@@ -29,6 +29,12 @@ public CancellationToken RequestAborted
}
}
+ ///
+ /// Gets whether null values should be propagated to nullable parents
+ /// (standard GraphQL behavior). When false, null stays at the field that caused it.
+ ///
+ public bool PropagateNullValues => _propagateNullValues;
+
///
public IFeatureCollection Features
{
diff --git a/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/BatchResolverTask.cs b/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/BatchResolverTask.cs
index 9b5ee8e95b6..c1a7cc19638 100644
--- a/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/BatchResolverTask.cs
+++ b/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/BatchResolverTask.cs
@@ -377,7 +377,15 @@ private void CompleteValues(
if (resultValue is { IsNullable: false, IsNullOrInvalidated: true })
{
- PropagateNullValues(resultValue);
+ if (_operationContext.PropagateNullValues)
+ {
+ PropagateNullValues(resultValue);
+ }
+ else
+ {
+ resultValue.SetNullValue();
+ }
+
_completionStatus = ExecutionTaskStatus.Faulted;
_operationContext.Result.AddNonNullViolation(context.Path);
_taskBuffer.Clear();
diff --git a/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/ResolverTask.CompleteValue.cs b/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/ResolverTask.CompleteValue.cs
index 74771cf956c..754b29bcc5d 100644
--- a/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/ResolverTask.CompleteValue.cs
+++ b/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/ResolverTask.CompleteValue.cs
@@ -44,7 +44,15 @@ private void CompleteValue(bool success, CancellationToken cancellationToken)
if (resultValue is { IsNullable: false, IsNullOrInvalidated: true })
{
- PropagateNullValues(resultValue);
+ if (_operationContext.PropagateNullValues)
+ {
+ PropagateNullValues(resultValue);
+ }
+ else
+ {
+ resultValue.SetNullValue();
+ }
+
_completionStatus = ExecutionTaskStatus.Faulted;
_operationContext.Result.AddNonNullViolation(_context.Path);
_taskBuffer.Clear();
diff --git a/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/ResolverTaskFactory.cs b/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/ResolverTaskFactory.cs
index 82b9974d910..5eb38716281 100644
--- a/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/ResolverTaskFactory.cs
+++ b/src/HotChocolate/Core/src/Types/Execution/Processing/Tasks/ResolverTaskFactory.cs
@@ -349,7 +349,15 @@ private static void ResolveAndCompleteInline(
if (fieldValue is { IsNullable: false, IsNullOrInvalidated: true })
{
- PropagateNullValues(fieldValue);
+ if (operationContext.PropagateNullValues)
+ {
+ PropagateNullValues(fieldValue);
+ }
+ else
+ {
+ fieldValue.SetNullValue();
+ }
+
operationContext.Result.AddNonNullViolation(fieldValue.Path);
}
}
diff --git a/src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs b/src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs
index 73281cd20f7..2729cbe797b 100644
--- a/src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs
+++ b/src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs
@@ -1,6 +1,7 @@
using System.Reflection;
using HotChocolate.Configuration;
using HotChocolate.Execution;
+using HotChocolate.Language;
using HotChocolate.Types;
namespace HotChocolate;
@@ -230,4 +231,9 @@ public interface IReadOnlySchemaOptions
/// Applies the @serializeAs directive to scalar types that specify a serialization format.
///
bool ApplySerializeAsToScalars { get; }
+
+ ///
+ /// Gets the default error handling mode for null propagation.
+ ///
+ ErrorHandlingMode DefaultErrorHandlingMode { get; }
}
diff --git a/src/HotChocolate/Core/src/Types/SchemaOptions.cs b/src/HotChocolate/Core/src/Types/SchemaOptions.cs
index ec5f50d5611..54d52b9e17d 100644
--- a/src/HotChocolate/Core/src/Types/SchemaOptions.cs
+++ b/src/HotChocolate/Core/src/Types/SchemaOptions.cs
@@ -1,6 +1,7 @@
using System.Reflection;
using HotChocolate.Configuration;
using HotChocolate.Execution;
+using HotChocolate.Language;
using HotChocolate.Types;
namespace HotChocolate;
@@ -189,6 +190,9 @@ public int OperationDocumentCacheSize
///
public bool ApplySerializeAsToScalars { get; set; }
+ ///
+ public ErrorHandlingMode DefaultErrorHandlingMode { get; set; } = ErrorHandlingMode.Propagate;
+
///
/// Creates a mutable options object from a read-only options object.
///
@@ -230,6 +234,7 @@ public static SchemaOptions FromOptions(IReadOnlySchemaOptions options)
ApplyShareableToPageInfo = options.ApplyShareableToPageInfo,
ApplyShareableToConnections = options.ApplyShareableToConnections,
ApplyShareableToNodeFields = options.ApplyShareableToNodeFields,
- ApplySerializeAsToScalars = options.ApplySerializeAsToScalars
+ ApplySerializeAsToScalars = options.ApplySerializeAsToScalars,
+ DefaultErrorHandlingMode = options.DefaultErrorHandlingMode
};
}
diff --git a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/OperationRequestBuilderTests.cs b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/OperationRequestBuilderTests.cs
index a80f53a55ca..c52f227c984 100644
--- a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/OperationRequestBuilderTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/OperationRequestBuilderTests.cs
@@ -315,7 +315,7 @@ public void BuildRequest_SetErrorHandlingMode()
var request =
OperationRequestBuilder.New()
.SetDocument("{ foo }")
- .SetErrorHandlingMode(ErrorHandlingMode.Halt)
+ .SetErrorHandlingMode(ErrorHandlingMode.Null)
.Build();
// assert
@@ -330,7 +330,7 @@ public void BuildRequest_SetErrorHandlingMode_VariableBatchRequest()
var request =
OperationRequestBuilder.New()
.SetDocument("{ foo }")
- .SetErrorHandlingMode(ErrorHandlingMode.Halt)
+ .SetErrorHandlingMode(ErrorHandlingMode.Null)
.SetVariableValues([new Dictionary { ["one"] = "foo" }])
.Build();
diff --git a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/__snapshots__/OperationRequestBuilderTests.BuildRequest_SetErrorHandlingMode.snap b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/__snapshots__/OperationRequestBuilderTests.BuildRequest_SetErrorHandlingMode.snap
index 6af0dd1b5d2..ef683929c7a 100644
--- a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/__snapshots__/OperationRequestBuilderTests.BuildRequest_SetErrorHandlingMode.snap
+++ b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/__snapshots__/OperationRequestBuilderTests.BuildRequest_SetErrorHandlingMode.snap
@@ -1,4 +1,4 @@
{
"document": "{ foo }",
- "errorHandlingMode": "Halt"
+ "errorHandlingMode": "Null"
}
diff --git a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/__snapshots__/OperationRequestBuilderTests.BuildRequest_SetErrorHandlingMode_VariableBatchRequest.snap b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/__snapshots__/OperationRequestBuilderTests.BuildRequest_SetErrorHandlingMode_VariableBatchRequest.snap
index 0276b4f5889..1566cd51489 100644
--- a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/__snapshots__/OperationRequestBuilderTests.BuildRequest_SetErrorHandlingMode_VariableBatchRequest.snap
+++ b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/Execution/__snapshots__/OperationRequestBuilderTests.BuildRequest_SetErrorHandlingMode_VariableBatchRequest.snap
@@ -1,6 +1,6 @@
{
"document": "{ foo }",
- "errorHandlingMode": "Halt",
+ "errorHandlingMode": "Null",
"variableValues": [
{
"one": "foo"
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/NullErrorPropagationTests.cs b/src/HotChocolate/Core/test/Execution.Tests/Errors/NullErrorPropagationTests.cs
index fdad9c24c36..233194550d3 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/Errors/NullErrorPropagationTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/NullErrorPropagationTests.cs
@@ -1,3 +1,4 @@
+using HotChocolate.Language;
using Microsoft.Extensions.DependencyInjection;
namespace HotChocolate.Execution;
@@ -148,33 +149,191 @@ public async Task Object_NonNullElementHasError(string fieldType)
snapshot.Add(result);
}
- private static async Task CreateExecutorAsync()
+ [InlineData("nonnull_prop")]
+ [InlineData("nullable_prop")]
+ [Theory]
+ public async Task Object_NonNullElementIsNull_NullMode(string fieldType)
{
- const string schema =
- """
- type Query {
- foo: Foo
- }
-
- type Foo {
- nullable_list_nullable_element: [Bar]
- nonnull_list_nullable_element: [Bar]!
- nullable_list_nonnull_element: [Bar!]
- nonnull_list_nonnull_element: [Bar!]!
- nonnull_prop: Bar!
- nullable_prop: Bar
- }
-
- type Bar {
- a: String
- b: String!
- c: String!
- }
- """;
+ // arrange
+ using var snapshot = SnapshotHelpers.StartResultSnapshot(fieldType);
+
+ var executor = await CreateExecutorAsync();
+ var request =
+ OperationRequestBuilder.New()
+ .SetDocument($"{{ foo {{ {fieldType} {{ b }} }} }}")
+ .AddGlobalState("b", null)
+ .SetErrorHandlingMode(ErrorHandlingMode.Null)
+ .Build();
+
+ // act
+ var result = await executor.ExecuteAsync(request);
+
+ // assert
+ snapshot.Add(result);
+ }
+
+ [InlineData("nonnull_prop")]
+ [InlineData("nullable_prop")]
+ [Theory]
+ public async Task Object_NonNullElementHasError_NullMode(string fieldType)
+ {
+ // arrange
+ using var snapshot = SnapshotHelpers.StartResultSnapshot(fieldType);
+
+ var executor = await CreateExecutorAsync();
+
+ var request =
+ OperationRequestBuilder.New()
+ .SetDocument($"{{ foo {{ {fieldType} {{ c }} }} }}")
+ .AddGlobalState("b", null)
+ .SetErrorHandlingMode(ErrorHandlingMode.Null)
+ .Build();
+
+ // act
+ var result = await executor.ExecuteAsync(request);
+
+ // assert
+ snapshot.Add(result);
+ }
+
+ [InlineData("nullable_list_nullable_element")]
+ [InlineData("nonnull_list_nullable_element")]
+ [InlineData("nullable_list_nonnull_element")]
+ [InlineData("nonnull_list_nonnull_element")]
+ [Theory]
+ public async Task List_NonNullElementIsNull_NullMode(string fieldType)
+ {
+ // arrange
+ using var snapshot = SnapshotHelpers.StartResultSnapshot(fieldType);
+
+ var executor = await CreateExecutorAsync();
+
+ var request =
+ OperationRequestBuilder.New()
+ .SetDocument($"{{ foo {{ {fieldType} {{ b }} }} }}")
+ .AddGlobalState("b", null)
+ .SetErrorHandlingMode(ErrorHandlingMode.Null)
+ .Build();
+
+ // act
+ var result = await executor.ExecuteAsync(request);
+
+ // assert
+ snapshot.Add(result);
+ }
+
+ [InlineData("nullable_list_nullable_element")]
+ [InlineData("nonnull_list_nullable_element")]
+ [InlineData("nullable_list_nonnull_element")]
+ [InlineData("nonnull_list_nonnull_element")]
+ [Theory]
+ public async Task List_NonNullElementHasError_NullMode(string fieldType)
+ {
+ // arrange
+ using var snapshot = SnapshotHelpers.StartResultSnapshot(fieldType);
+
+ var executor = await CreateExecutorAsync();
+
+ var request =
+ OperationRequestBuilder.New()
+ .SetDocument($"{{ foo {{ {fieldType} {{ c }} }} }}")
+ .AddGlobalState("b", null)
+ .SetErrorHandlingMode(ErrorHandlingMode.Null)
+ .Build();
+
+ // act
+ var result = await executor.ExecuteAsync(request);
+
+ // assert
+ snapshot.Add(result);
+ }
+
+ [Fact]
+ public async Task DefaultErrorHandlingMode_AppliesFromSchemaOptions()
+ {
+ // arrange
+ using var snapshot = SnapshotHelpers.StartResultSnapshot();
+
+ var executor = await new ServiceCollection()
+ .AddGraphQL()
+ .AddDocumentFromString(SchemaText)
+ .ModifyOptions(o => o.DefaultErrorHandlingMode = ErrorHandlingMode.Null)
+ .AddResolver("Query", "foo", _ => new(new object()))
+ .AddResolver("Foo", "nullable_list_nullable_element", _ => new(new[] { new object() }))
+ .AddResolver("Foo", "nonnull_list_nullable_element", _ => new(new[] { new object() }))
+ .AddResolver("Foo", "nullable_list_nonnull_element", _ => new(new[] { new object() }))
+ .AddResolver("Foo", "nonnull_list_nonnull_element", _ => new(new[] { new object() }))
+ .AddResolver("Foo", "nonnull_prop", _ => new(new object()))
+ .AddResolver("Foo", "nullable_prop", _ => new(new object()))
+ .AddResolver("Bar", "a", c => new(c.GetGlobalStateOrDefault("a")))
+ .AddResolver("Bar", "b", c => new(c.GetGlobalStateOrDefault("b")))
+ .AddResolver("Bar", "c", _ => throw new GraphQLException("ERROR"))
+ .BuildRequestExecutorAsync();
+
+ var request =
+ OperationRequestBuilder.New()
+ .SetDocument("{ foo { nonnull_prop { b } } }")
+ .AddGlobalState("b", null)
+ .Build();
+
+ // act
+ var result = await executor.ExecuteAsync(request);
+
+ // assert
+ snapshot.Add(result);
+ }
+
+ [Fact]
+ public async Task PerRequestOverride_OverridesSchemaDefault()
+ {
+ // arrange
+ using var snapshot = SnapshotHelpers.StartResultSnapshot();
+
+ // Server configured with Propagate (default), but request specifies Null
+ var executor = await CreateExecutorAsync();
+
+ var request =
+ OperationRequestBuilder.New()
+ .SetDocument("{ foo { nonnull_prop { b } } }")
+ .AddGlobalState("b", null)
+ .SetErrorHandlingMode(ErrorHandlingMode.Null)
+ .Build();
+
+ // act
+ var result = await executor.ExecuteAsync(request);
+
+ // assert
+ snapshot.Add(result);
+ }
+
+ private const string SchemaText =
+ """
+ type Query {
+ foo: Foo
+ }
+
+ type Foo {
+ nullable_list_nullable_element: [Bar]
+ nonnull_list_nullable_element: [Bar]!
+ nullable_list_nonnull_element: [Bar!]
+ nonnull_list_nonnull_element: [Bar!]!
+ nonnull_prop: Bar!
+ nullable_prop: Bar
+ }
+
+ type Bar {
+ a: String
+ b: String!
+ c: String!
+ }
+ """;
+
+ private static async Task CreateExecutorAsync()
+ {
return await new ServiceCollection()
.AddGraphQL()
- .AddDocumentFromString(schema)
+ .AddDocumentFromString(SchemaText)
.AddResolver("Query", "foo", _ => new(new object()))
.AddResolver("Foo", "nullable_list_nullable_element", _ => new(new[] { new object() }))
.AddResolver("Foo", "nonnull_list_nullable_element", _ => new(new[] { new object() }))
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.DefaultErrorHandlingMode_AppliesFromSchemaOptions.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.DefaultErrorHandlingMode_AppliesFromSchemaOptions.json
new file mode 100644
index 00000000000..2e33161e552
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.DefaultErrorHandlingMode_AppliesFromSchemaOptions.json
@@ -0,0 +1,22 @@
+{
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "foo",
+ "nonnull_prop",
+ "b"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ],
+ "data": {
+ "foo": {
+ "nonnull_prop": {
+ "b": null
+ }
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nonnull_list_nonnull_element.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nonnull_list_nonnull_element.json
new file mode 100644
index 00000000000..46880d293e0
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nonnull_list_nonnull_element.json
@@ -0,0 +1,22 @@
+{
+ "errors": [
+ {
+ "message": "ERROR",
+ "path": [
+ "foo",
+ "nonnull_list_nonnull_element",
+ 0,
+ "c"
+ ]
+ }
+ ],
+ "data": {
+ "foo": {
+ "nonnull_list_nonnull_element": [
+ {
+ "c": null
+ }
+ ]
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nonnull_list_nullable_element.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nonnull_list_nullable_element.json
new file mode 100644
index 00000000000..2c7a4699614
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nonnull_list_nullable_element.json
@@ -0,0 +1,22 @@
+{
+ "errors": [
+ {
+ "message": "ERROR",
+ "path": [
+ "foo",
+ "nonnull_list_nullable_element",
+ 0,
+ "c"
+ ]
+ }
+ ],
+ "data": {
+ "foo": {
+ "nonnull_list_nullable_element": [
+ {
+ "c": null
+ }
+ ]
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nullable_list_nonnull_element.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nullable_list_nonnull_element.json
new file mode 100644
index 00000000000..39ae16e0467
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nullable_list_nonnull_element.json
@@ -0,0 +1,22 @@
+{
+ "errors": [
+ {
+ "message": "ERROR",
+ "path": [
+ "foo",
+ "nullable_list_nonnull_element",
+ 0,
+ "c"
+ ]
+ }
+ ],
+ "data": {
+ "foo": {
+ "nullable_list_nonnull_element": [
+ {
+ "c": null
+ }
+ ]
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nullable_list_nullable_element.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nullable_list_nullable_element.json
new file mode 100644
index 00000000000..de96ec58d8a
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementHasError_NullMode_nullable_list_nullable_element.json
@@ -0,0 +1,22 @@
+{
+ "errors": [
+ {
+ "message": "ERROR",
+ "path": [
+ "foo",
+ "nullable_list_nullable_element",
+ 0,
+ "c"
+ ]
+ }
+ ],
+ "data": {
+ "foo": {
+ "nullable_list_nullable_element": [
+ {
+ "c": null
+ }
+ ]
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nonnull_list_nonnull_element.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nonnull_list_nonnull_element.json
new file mode 100644
index 00000000000..9513fed1eb1
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nonnull_list_nonnull_element.json
@@ -0,0 +1,25 @@
+{
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "foo",
+ "nonnull_list_nonnull_element",
+ 0,
+ "b"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ],
+ "data": {
+ "foo": {
+ "nonnull_list_nonnull_element": [
+ {
+ "b": null
+ }
+ ]
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nonnull_list_nullable_element.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nonnull_list_nullable_element.json
new file mode 100644
index 00000000000..68eb27688be
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nonnull_list_nullable_element.json
@@ -0,0 +1,25 @@
+{
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "foo",
+ "nonnull_list_nullable_element",
+ 0,
+ "b"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ],
+ "data": {
+ "foo": {
+ "nonnull_list_nullable_element": [
+ {
+ "b": null
+ }
+ ]
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nullable_list_nonnull_element.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nullable_list_nonnull_element.json
new file mode 100644
index 00000000000..882064373c3
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nullable_list_nonnull_element.json
@@ -0,0 +1,25 @@
+{
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "foo",
+ "nullable_list_nonnull_element",
+ 0,
+ "b"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ],
+ "data": {
+ "foo": {
+ "nullable_list_nonnull_element": [
+ {
+ "b": null
+ }
+ ]
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nullable_list_nullable_element.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nullable_list_nullable_element.json
new file mode 100644
index 00000000000..5ea169e9e6b
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.List_NonNullElementIsNull_NullMode_nullable_list_nullable_element.json
@@ -0,0 +1,25 @@
+{
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "foo",
+ "nullable_list_nullable_element",
+ 0,
+ "b"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ],
+ "data": {
+ "foo": {
+ "nullable_list_nullable_element": [
+ {
+ "b": null
+ }
+ ]
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementHasError_NullMode_nonnull_prop.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementHasError_NullMode_nonnull_prop.json
new file mode 100644
index 00000000000..14470cc494d
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementHasError_NullMode_nonnull_prop.json
@@ -0,0 +1,19 @@
+{
+ "errors": [
+ {
+ "message": "ERROR",
+ "path": [
+ "foo",
+ "nonnull_prop",
+ "c"
+ ]
+ }
+ ],
+ "data": {
+ "foo": {
+ "nonnull_prop": {
+ "c": null
+ }
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementHasError_NullMode_nullable_prop.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementHasError_NullMode_nullable_prop.json
new file mode 100644
index 00000000000..eecebf5f11f
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementHasError_NullMode_nullable_prop.json
@@ -0,0 +1,19 @@
+{
+ "errors": [
+ {
+ "message": "ERROR",
+ "path": [
+ "foo",
+ "nullable_prop",
+ "c"
+ ]
+ }
+ ],
+ "data": {
+ "foo": {
+ "nullable_prop": {
+ "c": null
+ }
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementIsNull_NullMode_nonnull_prop.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementIsNull_NullMode_nonnull_prop.json
new file mode 100644
index 00000000000..2e33161e552
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementIsNull_NullMode_nonnull_prop.json
@@ -0,0 +1,22 @@
+{
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "foo",
+ "nonnull_prop",
+ "b"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ],
+ "data": {
+ "foo": {
+ "nonnull_prop": {
+ "b": null
+ }
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementIsNull_NullMode_nullable_prop.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementIsNull_NullMode_nullable_prop.json
new file mode 100644
index 00000000000..75b281e7ff9
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.Object_NonNullElementIsNull_NullMode_nullable_prop.json
@@ -0,0 +1,22 @@
+{
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "foo",
+ "nullable_prop",
+ "b"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ],
+ "data": {
+ "foo": {
+ "nullable_prop": {
+ "b": null
+ }
+ }
+ }
+}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.PerRequestOverride_OverridesSchemaDefault.json b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.PerRequestOverride_OverridesSchemaDefault.json
new file mode 100644
index 00000000000..2e33161e552
--- /dev/null
+++ b/src/HotChocolate/Core/test/Execution.Tests/Errors/__snapshots__/NullErrorPropagationTests.PerRequestOverride_OverridesSchemaDefault.json
@@ -0,0 +1,22 @@
+{
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "foo",
+ "nonnull_prop",
+ "b"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ],
+ "data": {
+ "foo": {
+ "nonnull_prop": {
+ "b": null
+ }
+ }
+ }
+}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/ValueCompletion.cs b/src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/ValueCompletion.cs
index 86202ddf340..622db8ec3ac 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/ValueCompletion.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/ValueCompletion.cs
@@ -17,8 +17,7 @@ internal sealed class ValueCompletion
private readonly ISchemaDefinition _schema;
private readonly IErrorHandler _errorHandler;
private readonly ErrorHandlingMode _errorHandlingMode;
- private readonly bool _haltOnError;
- private readonly bool _haltOnNullViolation;
+ private readonly bool _propagateNullValues;
private readonly int _maxDepth;
public ValueCompletion(
@@ -34,8 +33,7 @@ public ValueCompletion(
_schema = schema;
_errorHandler = errorHandler;
_errorHandlingMode = errorHandlingMode;
- _haltOnError = errorHandlingMode is ErrorHandlingMode.Halt;
- _haltOnNullViolation = errorHandlingMode is ErrorHandlingMode.Propagate or ErrorHandlingMode.Halt;
+ _propagateNullValues = errorHandlingMode is not ErrorHandlingMode.Null;
_maxDepth = maxDepth;
}
@@ -118,8 +116,6 @@ public bool BuildResult(
return ApplyPocketedErrors(target);
- case ErrorHandlingMode.Halt:
- return false;
}
}
}
@@ -332,9 +328,6 @@ private bool ApplyFieldError(
switch (_errorHandlingMode)
{
- case ErrorHandlingMode.Halt:
- return false;
-
case ErrorHandlingMode.Propagate when selection.Type.Kind is TypeKind.NonNull:
var didPropagateToRoot = PropagateNullValues(fieldResult);
return !didPropagateToRoot;
@@ -412,7 +405,7 @@ private bool TryCompleteValue(
_store.AddError(error);
- return !_haltOnNullViolation;
+ return !_propagateNullValues;
}
type = type.InnerType();
@@ -446,11 +439,6 @@ private bool TryCompleteValue(
errorWithPath = _errorHandler.Handle(errorWithPath);
_store.AddError(errorWithPath);
-
- if (_haltOnError)
- {
- return false;
- }
}
else
{
@@ -542,17 +530,12 @@ private bool TryCompleteList(
errorWithPath = _errorHandler.Handle(errorWithPath);
_store.AddError(errorWithPath);
-
- if (_haltOnError)
- {
- return false;
- }
}
var elementValueKind = element.ValueKind;
if (elementValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
{
- if (isNonNull && _haltOnNullViolation)
+ if (isNonNull && _propagateNullValues)
{
return false;
}
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/CancellationTests.cs b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/CancellationTests.cs
index 0938f74eb70..1dc940cda7f 100644
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/CancellationTests.cs
+++ b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/CancellationTests.cs
@@ -46,89 +46,6 @@ public async Task Request_Is_Running_Into_Execution_Timeout_While_Http_Request_I
await MatchSnapshotAsync(gateway, request, result);
}
- [Fact]
- public async Task Execution_Is_Halted_While_Http_Request_In_Node_Is_Still_Ongoing()
- {
- // arrange
- using var server1 = CreateSourceSchema(
- "A",
- b => b
- .AddQueryType(),
- isTimingOut: true);
-
- using var server2 = CreateSourceSchema(
- "B",
- b => b
- .AddQueryType());
-
- using var gateway = await CreateCompositeSchemaAsync(
- [
- ("A", server1),
- ("B", server2)
- ],
- configureGatewayBuilder: builder =>
- builder.ModifyOptions(o => o.DefaultErrorHandlingMode = ErrorHandlingMode.Halt));
-
- using var client = GraphQLHttpClient.Create(gateway.CreateClient());
-
- var request = new OperationRequest(
- """
- {
- topProduct {
- id
- }
- reviews {
- id
- }
- }
- """);
-
- // act
- using var result = await client.PostAsync(
- request,
- new Uri("http://localhost:5000/graphql"));
-
- // assert
- await MatchSnapshotAsync(gateway, request, result);
- }
-
- [Fact]
- public async Task Execution_Is_Halted_While_Subscription_Is_Still_Ongoing()
- {
- // arrange
- using var server1 = CreateSourceSchema(
- "A",
- b => b
- .AddQueryType()
- .AddSubscriptionType());
-
- using var gateway = await CreateCompositeSchemaAsync(
- [
- ("A", server1)
- ],
- configureGatewayBuilder: builder =>
- builder.ModifyOptions(o => o.DefaultErrorHandlingMode = ErrorHandlingMode.Halt));
-
- using var client = GraphQLHttpClient.Create(gateway.CreateClient());
-
- var request = new OperationRequest(
- """
- subscription {
- onReviewCreated {
- id
- }
- }
- """);
-
- // act
- using var result = await client.PostAsync(
- request,
- new Uri("http://localhost:5000/graphql"));
-
- // assert
- await MatchSnapshotAsync(gateway, request, result);
- }
-
[Fact]
public async Task Http_Request_To_Source_Schema_Hits_HttpClient_Timeout()
{
@@ -165,41 +82,6 @@ public async Task Http_Request_To_Source_Schema_Hits_HttpClient_Timeout()
await MatchSnapshotAsync(gateway, request, result);
}
- [Fact]
- public async Task Default_ErrorHandlingMode_Can_Be_Changed()
- {
- // arrange
- using var server1 = CreateSourceSchema(
- "A",
- b => b.AddQueryType());
-
- using var gateway = await CreateCompositeSchemaAsync(
- [
- ("A", server1)
- ],
- configureGatewayBuilder: builder => builder
- .ModifyOptions(o => o.DefaultErrorHandlingMode = ErrorHandlingMode.Halt));
-
- var request = new OperationRequest(
- """
- {
- reviews {
- id
- }
- }
- """);
-
- // act
- using var client = GraphQLHttpClient.Create(gateway.CreateClient());
-
- using var result = await client.PostAsync(
- request,
- new Uri("http://localhost:5000/graphql"));
-
- // assert
- await MatchSnapshotAsync(gateway, request, result);
- }
-
public sealed class SourceSchema1
{
public class Query
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/SourceSchemaErrorTests.cs b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/SourceSchemaErrorTests.cs
index b02c9ad5c08..f0d4efd1e20 100644
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/SourceSchemaErrorTests.cs
+++ b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/SourceSchemaErrorTests.cs
@@ -15,7 +15,6 @@ public class SourceSchemaErrorTests : FusionTestBase
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task Error_On_Root_Field(ErrorHandlingMode onError)
{
// arrange
@@ -49,10 +48,44 @@ public async Task Error_On_Root_Field(ErrorHandlingMode onError)
await MatchSnapshotAsync(gateway, request, result, postFix: "OnError_" + onError);
}
+ [Fact]
+ public async Task SchemaDefault_Null_AppliesWithoutPerRequestOverride()
+ {
+ // arrange
+ using var server1 = CreateSourceSchema(
+ "A",
+ b => b.AddQueryType());
+
+ using var gateway = await CreateCompositeSchemaAsync(
+ [
+ ("A", server1)
+ ],
+ configureGatewayBuilder: builder =>
+ builder.ModifyOptions(o => o.DefaultErrorHandlingMode = ErrorHandlingMode.Null));
+
+ // act — no per-request onError override
+ using var client = GraphQLHttpClient.Create(gateway.CreateClient());
+
+ var request = new OperationRequest(
+ """
+ {
+ productById(id: 1) {
+ name
+ }
+ }
+ """);
+
+ using var result = await client.PostAsync(
+ request,
+ new Uri("http://localhost:5000/graphql"));
+
+ // assert
+ await MatchSnapshotAsync(gateway, request, result);
+ }
+
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task Error_On_Root_Leaf(ErrorHandlingMode onError)
{
// arrange
@@ -89,7 +122,6 @@ public async Task Error_On_Root_Leaf(ErrorHandlingMode onError)
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task No_Data_And_Error_With_Path_For_Root_Field_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -126,7 +158,6 @@ public async Task No_Data_And_Error_With_Path_For_Root_Field_NonNull(ErrorHandli
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task No_Data_And_Error_Without_Path_For_Root_Field(ErrorHandlingMode onError)
{
// arrange
@@ -178,7 +209,6 @@ public async Task No_Data_And_Error_Without_Path_For_Root_Field(ErrorHandlingMod
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task No_Data_And_Error_Without_Path_For_Root_Field_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -230,7 +260,6 @@ public async Task No_Data_And_Error_Without_Path_For_Root_Field_NonNull(ErrorHan
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task SourceSchema_Request_Fails_For_Root_Field(ErrorHandlingMode onError)
{
// arrange
@@ -268,7 +297,6 @@ public async Task SourceSchema_Request_Fails_For_Root_Field(ErrorHandlingMode on
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task SourceSchema_Request_Fails_For_Root_Field_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -310,7 +338,6 @@ public async Task SourceSchema_Request_Fails_For_Root_Field_NonNull(ErrorHandlin
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task Error_On_Lookup_Leaf(ErrorHandlingMode onError)
{
// arrange
@@ -353,7 +380,6 @@ public async Task Error_On_Lookup_Leaf(ErrorHandlingMode onError)
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task Error_On_Lookup_Field(ErrorHandlingMode onError)
{
// arrange
@@ -396,7 +422,6 @@ public async Task Error_On_Lookup_Field(ErrorHandlingMode onError)
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task Error_On_Lookup_Leaf_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -439,7 +464,6 @@ public async Task Error_On_Lookup_Leaf_NonNull(ErrorHandlingMode onError)
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task Error_On_Lookup_Field_In_List(ErrorHandlingMode onError)
{
// arrange
@@ -482,7 +506,6 @@ public async Task Error_On_Lookup_Field_In_List(ErrorHandlingMode onError)
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task Error_On_Lookup_Leaf_In_List(ErrorHandlingMode onError)
{
// arrange
@@ -525,7 +548,6 @@ public async Task Error_On_Lookup_Leaf_In_List(ErrorHandlingMode onError)
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task Error_On_Lookup_Leaf_In_List_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -568,7 +590,6 @@ public async Task Error_On_Lookup_Leaf_In_List_NonNull(ErrorHandlingMode onError
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task No_Data_And_Error_With_Path_For_Lookup_Field_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -611,7 +632,6 @@ public async Task No_Data_And_Error_With_Path_For_Lookup_Field_NonNull(ErrorHand
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task No_Data_And_Error_With_Path_For_Lookup_Leaf_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -654,7 +674,6 @@ public async Task No_Data_And_Error_With_Path_For_Lookup_Leaf_NonNull(ErrorHandl
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task No_Data_And_Error_Without_Path_For_Lookup_Field_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -712,7 +731,6 @@ public async Task No_Data_And_Error_Without_Path_For_Lookup_Field_NonNull(ErrorH
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task SourceSchema_Request_Fails_For_Lookup(ErrorHandlingMode onError)
{
// arrange
@@ -756,7 +774,6 @@ public async Task SourceSchema_Request_Fails_For_Lookup(ErrorHandlingMode onErro
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task SourceSchema_Request_Fails_For_Lookup_NonNull(ErrorHandlingMode onError)
{
// arrange
@@ -800,7 +817,6 @@ public async Task SourceSchema_Request_Fails_For_Lookup_NonNull(ErrorHandlingMod
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task SourceSchema_Request_Fails_For_Lookup_On_List(ErrorHandlingMode onError)
{
// arrange
@@ -844,7 +860,6 @@ public async Task SourceSchema_Request_Fails_For_Lookup_On_List(ErrorHandlingMod
[Theory]
[InlineData(ErrorHandlingMode.Propagate)]
[InlineData(ErrorHandlingMode.Null)]
- [InlineData(ErrorHandlingMode.Halt)]
public async Task SourceSchema_Request_Fails_For_Lookup_On_List_NonNull(ErrorHandlingMode onError)
{
// arrange
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Default_ErrorHandlingMode_Can_Be_Changed.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Default_ErrorHandlingMode_Can_Be_Changed.yaml
deleted file mode 100644
index 8e090582311..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Default_ErrorHandlingMode_Can_Be_Changed.yaml
+++ /dev/null
@@ -1,79 +0,0 @@
-title: Default_ErrorHandlingMode_Can_Be_Changed
-request:
- document: |
- {
- reviews {
- id
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve reviews",
- "path": [
- "reviews"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Query {
- reviews: [Review!]
- }
-
- type Review {
- id: Int!
- }
- interactions:
- - request:
- document: |
- query Op_ef4ed803_1 {
- reviews {
- id
- }
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve reviews",
- "path": [
- "reviews"
- ]
- }
- ],
- "data": {
- "reviews": null
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- reviews {
- id
- }
- }
- hash: ef4ed8030ea8e8d1331adb3822f96a9c
- searchSpace: 1
- expandedNodes: 1
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_ef4ed803_1 {
- reviews {
- id
- }
- }
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Execution_Is_Halted_While_Http_Request_In_Node_Is_Still_Ongoing.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Execution_Is_Halted_While_Http_Request_In_Node_Is_Still_Ongoing.yaml
deleted file mode 100644
index 306013b20a0..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Execution_Is_Halted_While_Http_Request_In_Node_Is_Still_Ongoing.yaml
+++ /dev/null
@@ -1,116 +0,0 @@
-title: Execution_Is_Halted_While_Http_Request_In_Node_Is_Still_Ongoing
-request:
- document: |
- {
- topProduct {
- id
- }
- reviews {
- id
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve reviews",
- "path": [
- "reviews"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- }
-
- type Query {
- topProduct: Product
- }
- isTimingOut: true
- interactions:
- - request:
- document: |
- query Op_512ba6dc_1 {
- topProduct {
- id
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Query {
- reviews: [Review!]
- }
-
- type Review {
- id: Int!
- }
- interactions:
- - request:
- document: |
- query Op_512ba6dc_2 {
- reviews {
- id
- }
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve reviews",
- "path": [
- "reviews"
- ]
- }
- ],
- "data": {
- "reviews": null
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- id
- }
- reviews {
- id
- }
- }
- hash: 512ba6dc13ede1ded2da8cd00532a486
- searchSpace: 2
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_512ba6dc_1 {
- topProduct {
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_512ba6dc_2 {
- reviews {
- id
- }
- }
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Execution_Is_Halted_While_Subscription_Is_Still_Ongoing.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Execution_Is_Halted_While_Subscription_Is_Still_Ongoing.yaml
deleted file mode 100644
index cb344053578..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/CancellationTests.Execution_Is_Halted_While_Subscription_Is_Still_Ongoing.yaml
+++ /dev/null
@@ -1,101 +0,0 @@
-title: Execution_Is_Halted_While_Subscription_Is_Still_Ongoing
-request:
- document: |
- subscription {
- onReviewCreated {
- id
- }
- }
-responseStream:
- - body: |
- {
- "data": {
- "onReviewCreated": {
- "id": 1
- }
- }
- }
- - body: |
- {
- "errors": [
- {
- "message": "Could not produce review",
- "path": [
- "onReviewCreated"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- subscription: Subscription
- }
-
- type Query {
- reviews: [Review!]
- }
-
- type Review {
- id: Int!
- }
-
- type Subscription {
- onReviewCreated: Review
- }
- interactions:
- - request:
- document: |
- subscription Op_1c7b790e_1 {
- onReviewCreated {
- id
- }
- }
- response:
- contentType: application/jsonl; charset=utf-8
- results:
- - |
- {
- "data": {
- "onReviewCreated": {
- "id": 1
- }
- }
- }
- - |
- {
- "errors": [
- {
- "message": "Could not produce review",
- "path": [
- "onReviewCreated"
- ]
- }
- ],
- "data": {
- "onReviewCreated": null
- }
- }
-operationPlan:
- operation:
- - document: |
- subscription {
- onReviewCreated {
- id
- }
- }
- hash: 1c7b790e223d28e348d3e04a33527c96
- searchSpace: 1
- expandedNodes: 1
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- subscription Op_1c7b790e_1 {
- onReviewCreated {
- id
- }
- }
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Field_In_List_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Field_In_List_OnError_Halt.yaml
deleted file mode 100644
index bcbbc586388..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Field_In_List_OnError_Halt.yaml
+++ /dev/null
@@ -1,196 +0,0 @@
-title: Error_On_Lookup_Field_In_List
-request:
- onError: Halt
- document: |
- {
- topProducts {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "topProducts",
- 0,
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProducts": [
- {
- "price": 13.99,
- "id": 1
- },
- {
- "price": 13.99,
- "id": 2
- },
- {
- "price": 13.99,
- "id": 3
- }
- ]
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- [
- {
- "__fusion_1_id": 1
- },
- {
- "__fusion_1_id": 2
- },
- {
- "__fusion_1_id": 3
- }
- ]
- response:
- contentType: application/jsonl; charset=utf-8
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": {
- "productById": null
- }
- }
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": {
- "productById": null
- }
- }
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": {
- "productById": null
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- topProducts {
- price
- name
- id @fusion__requirement
- }
- }
- hash: 67b3f75afa8d6eb979605a59d5462c1d
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProducts
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Field_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Field_OnError_Halt.yaml
deleted file mode 100644
index 254c4929f8a..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Field_OnError_Halt.yaml
+++ /dev/null
@@ -1,148 +0,0 @@
-title: Error_On_Lookup_Field
-request:
- onError: Halt
- document: |
- {
- topProduct {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "topProduct",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProduct": {
- "price": 13.99,
- "id": 1
- }
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- {
- "__fusion_1_id": 1
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": {
- "productById": null
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- price
- name
- id @fusion__requirement
- }
- }
- hash: e24d93b6245cedd878fff4452f5f16b9
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProduct
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_In_List_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_In_List_NonNull_OnError_Halt.yaml
deleted file mode 100644
index fdf6ce7c33e..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_In_List_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,196 +0,0 @@
-title: Error_On_Lookup_Leaf_In_List_NonNull
-request:
- onError: Halt
- document: |
- {
- topProducts {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "topProducts",
- 0,
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProducts": [
- {
- "price": 13.99,
- "id": 1
- },
- {
- "price": 13.99,
- "id": 2
- },
- {
- "price": 13.99,
- "id": 3
- }
- ]
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- [
- {
- "__fusion_1_id": 1
- },
- {
- "__fusion_1_id": 2
- },
- {
- "__fusion_1_id": 3
- }
- ]
- response:
- contentType: application/jsonl; charset=utf-8
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": {
- "productById": null
- }
- }
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": {
- "productById": null
- }
- }
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": {
- "productById": null
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- topProducts {
- price
- name
- id @fusion__requirement
- }
- }
- hash: 67b3f75afa8d6eb979605a59d5462c1d
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProducts
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_In_List_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_In_List_OnError_Halt.yaml
deleted file mode 100644
index 63792a255e4..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_In_List_OnError_Halt.yaml
+++ /dev/null
@@ -1,205 +0,0 @@
-title: Error_On_Lookup_Leaf_In_List
-request:
- onError: Halt
- document: |
- {
- topProducts {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "topProducts",
- 0,
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProducts": [
- {
- "price": 13.99,
- "id": 1
- },
- {
- "price": 13.99,
- "id": 2
- },
- {
- "price": 13.99,
- "id": 3
- }
- ]
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- [
- {
- "__fusion_1_id": 1
- },
- {
- "__fusion_1_id": 2
- },
- {
- "__fusion_1_id": 3
- }
- ]
- response:
- contentType: application/jsonl; charset=utf-8
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "productById",
- "name"
- ]
- }
- ],
- "data": {
- "productById": {
- "name": null
- }
- }
- }
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "productById",
- "name"
- ]
- }
- ],
- "data": {
- "productById": {
- "name": null
- }
- }
- }
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "productById",
- "name"
- ]
- }
- ],
- "data": {
- "productById": {
- "name": null
- }
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- topProducts {
- price
- name
- id @fusion__requirement
- }
- }
- hash: 67b3f75afa8d6eb979605a59d5462c1d
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProducts
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_NonNull_OnError_Halt.yaml
deleted file mode 100644
index 967f0e18f1d..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,148 +0,0 @@
-title: Error_On_Lookup_Leaf_NonNull
-request:
- onError: Halt
- document: |
- {
- topProduct {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "topProduct",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProduct": {
- "price": 13.99,
- "id": 1
- }
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- {
- "__fusion_1_id": 1
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": {
- "productById": null
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- price
- name
- id @fusion__requirement
- }
- }
- hash: e24d93b6245cedd878fff4452f5f16b9
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProduct
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_OnError_Halt.yaml
deleted file mode 100644
index 0daa0ed0b57..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Lookup_Leaf_OnError_Halt.yaml
+++ /dev/null
@@ -1,151 +0,0 @@
-title: Error_On_Lookup_Leaf
-request:
- onError: Halt
- document: |
- {
- topProduct {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "topProduct",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProduct": {
- "price": 13.99,
- "id": 1
- }
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- {
- "__fusion_1_id": 1
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "productById",
- "name"
- ]
- }
- ],
- "data": {
- "productById": {
- "name": null
- }
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- price
- name
- id @fusion__requirement
- }
- }
- hash: e24d93b6245cedd878fff4452f5f16b9
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProduct
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Root_Leaf_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Root_Leaf_OnError_Halt.yaml
deleted file mode 100644
index d776c666f0a..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Root_Leaf_OnError_Halt.yaml
+++ /dev/null
@@ -1,85 +0,0 @@
-title: Error_On_Root_Leaf
-request:
- onError: Halt
- document: |
- {
- productById(id: 1) {
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "productById",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_97fd38fc_1 {
- productById(id: 1) {
- name
- }
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "productById",
- "name"
- ]
- }
- ],
- "data": {
- "productById": {
- "name": null
- }
- }
- }
-operationPlan:
- operation:
- - document: |
- {
- productById(id: 1) {
- name
- }
- }
- hash: 97fd38fcea394bc6badd7ea22c6de660
- searchSpace: 1
- expandedNodes: 1
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_97fd38fc_1 {
- productById(id: 1) {
- name
- }
- }
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Lookup_Field_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Lookup_Field_NonNull_OnError_Halt.yaml
deleted file mode 100644
index 89a938ed424..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Lookup_Field_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,146 +0,0 @@
-title: No_Data_And_Error_With_Path_For_Lookup_Field_NonNull
-request:
- onError: Halt
- document: |
- {
- topProduct {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "topProduct",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProduct": {
- "price": 13.99,
- "id": 1
- }
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product! @lookup
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- {
- "__fusion_1_id": 1
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": null
- }
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- price
- name
- id @fusion__requirement
- }
- }
- hash: e24d93b6245cedd878fff4452f5f16b9
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProduct
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Lookup_Leaf_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Lookup_Leaf_NonNull_OnError_Halt.yaml
deleted file mode 100644
index bb5458435e8..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Lookup_Leaf_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,147 +0,0 @@
-title: No_Data_And_Error_With_Path_For_Lookup_Leaf_NonNull
-request:
- onError: Halt
- document: |
- {
- topProduct {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "topProduct",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProduct": {
- "price": 13.99,
- "id": 1
- }
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product! @lookup
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- {
- "__fusion_1_id": 1
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product.name",
- "path": [
- "productById",
- "name"
- ]
- }
- ],
- "data": null
- }
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- price
- name
- id @fusion__requirement
- }
- }
- hash: e24d93b6245cedd878fff4452f5f16b9
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProduct
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Root_Field_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Root_Field_NonNull_OnError_Halt.yaml
deleted file mode 100644
index 3381500bd30..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_With_Path_For_Root_Field_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,79 +0,0 @@
-title: No_Data_And_Error_With_Path_For_Root_Field_NonNull
-request:
- onError: Halt
- document: |
- {
- productById(id: 1) {
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product! @lookup
- }
- interactions:
- - request:
- document: |
- query Op_97fd38fc_1 {
- productById(id: 1) {
- name
- }
- }
- response:
- results:
- - |
- {
- "errors": [
- {
- "message": "Could not resolve Product",
- "path": [
- "productById"
- ]
- }
- ],
- "data": null
- }
-operationPlan:
- operation:
- - document: |
- {
- productById(id: 1) {
- name
- }
- }
- hash: 97fd38fcea394bc6badd7ea22c6de660
- searchSpace: 1
- expandedNodes: 1
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_97fd38fc_1 {
- productById(id: 1) {
- name
- }
- }
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Lookup_Field_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Lookup_Field_NonNull_OnError_Halt.yaml
deleted file mode 100644
index b680c4a5451..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Lookup_Field_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,146 +0,0 @@
-title: No_Data_And_Error_Without_Path_For_Lookup_Field_NonNull
-request:
- onError: Halt
- document: |
- {
- topProduct {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "A global error"
- },
- {
- "message": "Unexpected Execution Error",
- "path": [
- "topProduct",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProduct": {
- "price": 13.99,
- "id": 1
- }
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- {
- "__fusion_1_id": 1
- }
- response:
- statusCode: 400
- results:
- - |
- {
- "errors": [
- {
- "message": "A global error"
- }
- ]
- }
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- price
- name
- id @fusion__requirement
- }
- }
- hash: e24d93b6245cedd878fff4452f5f16b9
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProduct
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Root_Field_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Root_Field_NonNull_OnError_Halt.yaml
deleted file mode 100644
index e5d8b4929cd..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Root_Field_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,79 +0,0 @@
-title: No_Data_And_Error_Without_Path_For_Root_Field_NonNull
-request:
- onError: Halt
- document: |
- {
- productById(id: 1) {
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "A global error"
- },
- {
- "message": "Unexpected Execution Error",
- "path": [
- "productById"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product! @lookup
- }
- interactions:
- - request:
- document: |
- query Op_97fd38fc_1 {
- productById(id: 1) {
- name
- }
- }
- response:
- statusCode: 400
- results:
- - |
- {
- "errors": [
- {
- "message": "A global error"
- }
- ]
- }
-operationPlan:
- operation:
- - document: |
- {
- productById(id: 1) {
- name
- }
- }
- hash: 97fd38fcea394bc6badd7ea22c6de660
- searchSpace: 1
- expandedNodes: 1
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_97fd38fc_1 {
- productById(id: 1) {
- name
- }
- }
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Root_Field_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Root_Field_OnError_Halt.yaml
deleted file mode 100644
index 5e5a4a37e82..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.No_Data_And_Error_Without_Path_For_Root_Field_OnError_Halt.yaml
+++ /dev/null
@@ -1,79 +0,0 @@
-title: No_Data_And_Error_Without_Path_For_Root_Field
-request:
- onError: Halt
- document: |
- {
- productById(id: 1) {
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "A global error"
- },
- {
- "message": "Unexpected Execution Error",
- "path": [
- "productById"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_97fd38fc_1 {
- productById(id: 1) {
- name
- }
- }
- response:
- statusCode: 400
- results:
- - |
- {
- "errors": [
- {
- "message": "A global error"
- }
- ]
- }
-operationPlan:
- operation:
- - document: |
- {
- productById(id: 1) {
- name
- }
- }
- hash: 97fd38fcea394bc6badd7ea22c6de660
- searchSpace: 1
- expandedNodes: 1
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_97fd38fc_1 {
- productById(id: 1) {
- name
- }
- }
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Root_Field_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SchemaDefault_Null_AppliesWithoutPerRequestOverride.yaml
similarity index 92%
rename from src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Root_Field_OnError_Halt.yaml
rename to src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SchemaDefault_Null_AppliesWithoutPerRequestOverride.yaml
index 1e9f0d0b0ba..2206b7feac0 100644
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.Error_On_Root_Field_OnError_Halt.yaml
+++ b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SchemaDefault_Null_AppliesWithoutPerRequestOverride.yaml
@@ -1,6 +1,5 @@
-title: Error_On_Root_Field
+title: SchemaDefault_Null_AppliesWithoutPerRequestOverride
request:
- onError: Halt
document: |
{
productById(id: 1) {
@@ -10,6 +9,9 @@ request:
response:
body: |
{
+ "data": {
+ "productById": null
+ },
"errors": [
{
"message": "Could not resolve Product",
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_NonNull_OnError_Halt.yaml
deleted file mode 100644
index b0fa19101a3..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,134 +0,0 @@
-title: SourceSchema_Request_Fails_For_Lookup_NonNull
-request:
- onError: Halt
- document: |
- {
- topProduct {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Unexpected Execution Error",
- "path": [
- "topProduct",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProduct": {
- "price": 13.99,
- "id": 1
- }
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- {
- "__fusion_1_id": 1
- }
- response:
- statusCode: 500
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- price
- name
- id @fusion__requirement
- }
- }
- hash: e24d93b6245cedd878fff4452f5f16b9
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_e24d93b6_1 {
- topProduct {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_e24d93b6_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProduct
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_OnError_Halt.yaml
deleted file mode 100644
index 80e0746ba48..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_OnError_Halt.yaml
+++ /dev/null
@@ -1,134 +0,0 @@
-title: SourceSchema_Request_Fails_For_Lookup
-request:
- onError: Halt
- document: |
- {
- nullableTopProduct {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Unexpected Execution Error",
- "path": [
- "nullableTopProduct",
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_12015865_1 {
- nullableTopProduct {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "nullableTopProduct": {
- "price": 13.99,
- "id": 1
- }
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_12015865_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- {
- "__fusion_1_id": 1
- }
- response:
- statusCode: 500
-operationPlan:
- operation:
- - document: |
- {
- nullableTopProduct {
- price
- name
- id @fusion__requirement
- }
- }
- hash: 12015865a78f4ab2330778c5486a4026
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_12015865_1 {
- nullableTopProduct {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_12015865_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.nullableTopProduct
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_On_List_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_On_List_NonNull_OnError_Halt.yaml
deleted file mode 100644
index 4a70b7a3081..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_On_List_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,153 +0,0 @@
-title: SourceSchema_Request_Fails_For_Lookup_On_List_NonNull
-request:
- onError: Halt
- document: |
- {
- topProducts {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Unexpected Execution Error",
- "path": [
- "topProducts",
- 0,
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProducts": [
- {
- "price": 13.99,
- "id": 1
- },
- {
- "price": 13.99,
- "id": 2
- },
- {
- "price": 13.99,
- "id": 3
- }
- ]
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String!
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- [
- {
- "__fusion_1_id": 1
- },
- {
- "__fusion_1_id": 2
- },
- {
- "__fusion_1_id": 3
- }
- ]
- response:
- statusCode: 500
-operationPlan:
- operation:
- - document: |
- {
- topProducts {
- price
- name
- id @fusion__requirement
- }
- }
- hash: 67b3f75afa8d6eb979605a59d5462c1d
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProducts
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_On_List_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_On_List_OnError_Halt.yaml
deleted file mode 100644
index 21e2505a121..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Lookup_On_List_OnError_Halt.yaml
+++ /dev/null
@@ -1,153 +0,0 @@
-title: SourceSchema_Request_Fails_For_Lookup_On_List
-request:
- onError: Halt
- document: |
- {
- topProducts {
- price
- name
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Unexpected Execution Error",
- "path": [
- "topProducts",
- 0,
- "name"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- response:
- results:
- - |
- {
- "data": {
- "topProducts": [
- {
- "price": 13.99,
- "id": 1
- },
- {
- "price": 13.99,
- "id": 2
- },
- {
- "price": 13.99,
- "id": 3
- }
- ]
- }
- }
- - name: B
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- name: String
- id: Int!
- }
-
- type Query {
- productById(id: Int!): Product @lookup
- }
- interactions:
- - request:
- document: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- variables: |
- [
- {
- "__fusion_1_id": 1
- },
- {
- "__fusion_1_id": 2
- },
- {
- "__fusion_1_id": 3
- }
- ]
- response:
- statusCode: 500
-operationPlan:
- operation:
- - document: |
- {
- topProducts {
- price
- name
- id @fusion__requirement
- }
- }
- hash: 67b3f75afa8d6eb979605a59d5462c1d
- searchSpace: 1
- expandedNodes: 2
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_67b3f75a_1 {
- topProducts {
- price
- id
- }
- }
- - id: 2
- type: Operation
- schema: B
- operation: |
- query Op_67b3f75a_2(
- $__fusion_1_id: Int!
- ) {
- productById(id: $__fusion_1_id) {
- name
- }
- }
- source: $.productById
- target: $.topProducts
- requirements:
- - name: __fusion_1_id
- selectionMap: >-
- id
- dependencies:
- - id: 1
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Root_Field_NonNull_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Root_Field_NonNull_OnError_Halt.yaml
deleted file mode 100644
index 0f9cdf97106..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Root_Field_NonNull_OnError_Halt.yaml
+++ /dev/null
@@ -1,70 +0,0 @@
-title: SourceSchema_Request_Fails_For_Root_Field_NonNull
-request:
- onError: Halt
- document: |
- {
- topProduct {
- price
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Unexpected Execution Error",
- "path": [
- "topProduct"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_1c1cf024_1 {
- topProduct {
- price
- }
- }
- response:
- statusCode: 500
-operationPlan:
- operation:
- - document: |
- {
- topProduct {
- price
- }
- }
- hash: 1c1cf0244bcda9f7f91e7e0becca0616
- searchSpace: 1
- expandedNodes: 1
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_1c1cf024_1 {
- topProduct {
- price
- }
- }
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Root_Field_OnError_Halt.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Root_Field_OnError_Halt.yaml
deleted file mode 100644
index 7f26f9e3c7a..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/SourceSchemaErrorTests.SourceSchema_Request_Fails_For_Root_Field_OnError_Halt.yaml
+++ /dev/null
@@ -1,70 +0,0 @@
-title: SourceSchema_Request_Fails_For_Root_Field
-request:
- onError: Halt
- document: |
- {
- nullableTopProduct {
- price
- }
- }
-response:
- body: |
- {
- "errors": [
- {
- "message": "Unexpected Execution Error",
- "path": [
- "nullableTopProduct"
- ]
- }
- ]
- }
-sourceSchemas:
- - name: A
- schema: |
- schema {
- query: Query
- }
-
- type Product {
- id: Int!
- price: Float!
- }
-
- type Query {
- topProduct: Product!
- nullableTopProduct: Product
- topProducts: [Product!]!
- productById(id: Int!): Product @lookup @internal
- }
- interactions:
- - request:
- document: |
- query Op_14c79a43_1 {
- nullableTopProduct {
- price
- }
- }
- response:
- statusCode: 500
-operationPlan:
- operation:
- - document: |
- {
- nullableTopProduct {
- price
- }
- }
- hash: 14c79a43eb6ce3e1a1fa16337c365654
- searchSpace: 1
- expandedNodes: 1
- nodes:
- - id: 1
- type: Operation
- schema: A
- operation: |
- query Op_14c79a43_1 {
- nullableTopProduct {
- price
- }
- }
diff --git a/src/HotChocolate/Language/src/Language.Web/ErrorHandlingMode.cs b/src/HotChocolate/Language/src/Language.Web/ErrorHandlingMode.cs
index 281d6d77e4b..1ff5a7653f6 100644
--- a/src/HotChocolate/Language/src/Language.Web/ErrorHandlingMode.cs
+++ b/src/HotChocolate/Language/src/Language.Web/ErrorHandlingMode.cs
@@ -3,6 +3,5 @@ namespace HotChocolate.Language;
public enum ErrorHandlingMode
{
Propagate = 0,
- Null = 1,
- Halt = 2
+ Null = 1
}
diff --git a/src/HotChocolate/Language/src/Language.Web/Properties/LangWebResources.Designer.cs b/src/HotChocolate/Language/src/Language.Web/Properties/LangWebResources.Designer.cs
index 42e5de20c66..70f8b407a73 100644
--- a/src/HotChocolate/Language/src/Language.Web/Properties/LangWebResources.Designer.cs
+++ b/src/HotChocolate/Language/src/Language.Web/Properties/LangWebResources.Designer.cs
@@ -104,6 +104,12 @@ internal static string ThrowHelper_InvalidOnErrorValue {
return ResourceManager.GetString("ThrowHelper_InvalidOnErrorValue", resourceCulture);
}
}
+
+ internal static string ThrowHelper_UnknownOnErrorValue {
+ get {
+ return ResourceManager.GetString("ThrowHelper_UnknownOnErrorValue", resourceCulture);
+ }
+ }
internal static string Utf8GraphQLRequestParser_Parse_EmptyJSONDocument {
get {
diff --git a/src/HotChocolate/Language/src/Language.Web/Properties/LangWebResources.resx b/src/HotChocolate/Language/src/Language.Web/Properties/LangWebResources.resx
index f989044553e..27a3f8f93e6 100644
--- a/src/HotChocolate/Language/src/Language.Web/Properties/LangWebResources.resx
+++ b/src/HotChocolate/Language/src/Language.Web/Properties/LangWebResources.resx
@@ -48,6 +48,9 @@
Invalid 'onError' value. Expected string or null, but got {0}.
+
+ Unknown 'onError' value '{0}'. Allowed values are 'PROPAGATE' or 'NULL'.
+
Empty JSON document.
diff --git a/src/HotChocolate/Language/src/Language.Web/ThrowHelper.cs b/src/HotChocolate/Language/src/Language.Web/ThrowHelper.cs
index fcbd9f39f72..4f7c6e736a1 100644
--- a/src/HotChocolate/Language/src/Language.Web/ThrowHelper.cs
+++ b/src/HotChocolate/Language/src/Language.Web/ThrowHelper.cs
@@ -34,6 +34,12 @@ public static InvalidGraphQLRequestException InvalidOnErrorValue(JsonTokenType t
ThrowHelper_InvalidOnErrorValue,
tokenType));
+ public static InvalidGraphQLRequestException UnknownOnErrorValue(string? value)
+ => new(string.Format(
+ CultureInfo.InvariantCulture,
+ ThrowHelper_UnknownOnErrorValue,
+ value));
+
public static InvalidGraphQLRequestException InvalidVariablesValue(JsonTokenType tokenType)
=> new(string.Format(
CultureInfo.InvariantCulture,
diff --git a/src/HotChocolate/Language/src/Language.Web/Utf8GraphQLRequestParser.cs b/src/HotChocolate/Language/src/Language.Web/Utf8GraphQLRequestParser.cs
index f2cf19074eb..aeea912cef9 100644
--- a/src/HotChocolate/Language/src/Language.Web/Utf8GraphQLRequestParser.cs
+++ b/src/HotChocolate/Language/src/Language.Web/Utf8GraphQLRequestParser.cs
@@ -253,8 +253,7 @@ private readonly GraphQLRequest ParseRequest(ref Utf8JsonReader reader, Operatio
{
"PROPAGATE" => ErrorHandlingMode.Propagate,
"NULL" => ErrorHandlingMode.Null,
- "HALT" => ErrorHandlingMode.Halt,
- _ => null
+ _ => throw ThrowHelper.UnknownOnErrorValue(mode)
};
}
else if (reader.TokenType == JsonTokenType.Null)
diff --git a/src/HotChocolate/Language/test/Language.Web.Tests/Utf8GraphQLRequestParserTests.cs b/src/HotChocolate/Language/test/Language.Web.Tests/Utf8GraphQLRequestParserTests.cs
index cba67360c1c..789b00fc776 100644
--- a/src/HotChocolate/Language/test/Language.Web.Tests/Utf8GraphQLRequestParserTests.cs
+++ b/src/HotChocolate/Language/test/Language.Web.Tests/Utf8GraphQLRequestParserTests.cs
@@ -248,12 +248,9 @@ public void Parse_Id_As_Name()
[Theory]
[InlineData("PROPAGATE", ErrorHandlingMode.Propagate)]
[InlineData("NULL", ErrorHandlingMode.Null)]
- [InlineData("HALT", ErrorHandlingMode.Halt)]
[InlineData("propagate", ErrorHandlingMode.Propagate)]
[InlineData("null", ErrorHandlingMode.Null)]
- [InlineData("halt", ErrorHandlingMode.Halt)]
[InlineData(null, null)]
- [InlineData("bla", null)]
public void Parse_OnError(string? onError, ErrorHandlingMode? expectedErrorHandlingMode)
{
// arrange
@@ -1046,6 +1043,18 @@ public void Parse_OperationName_Invalid_Type_Array_Throws()
Assert.Contains("operationName", exception.Message, StringComparison.OrdinalIgnoreCase);
}
+ [Fact]
+ public void Parse_OnError_Unknown_Value_Throws()
+ {
+ // arrange
+ var source = "{\"onError\": \"HALT\", \"query\": \"{ __typename }\"}"u8.ToArray();
+
+ // act & assert
+ var exception = Assert.Throws(
+ () => Utf8GraphQLRequestParser.Parse(source));
+ Assert.Contains("onError", exception.Message, StringComparison.OrdinalIgnoreCase);
+ }
+
[Fact]
public void Parse_OnError_Invalid_Type_Number_Throws()
{
@@ -1062,7 +1071,7 @@ public void Parse_OnError_Invalid_Type_Number_Throws()
public void Parse_OnError_Invalid_Type_Object_Throws()
{
// arrange
- var source = "{\"onError\": {\"mode\": \"HALT\"}, \"query\": \"{ __typename }\"}"u8.ToArray();
+ var source = "{\"onError\": {\"mode\": \"NULL\"}, \"query\": \"{ __typename }\"}"u8.ToArray();
// act & assert
var exception = Assert.Throws(