Skip to content

Commit f00c4ca

Browse files
[Fusion] Support new error handling modes (#8612)
1 parent 4ecb40d commit f00c4ca

File tree

148 files changed

+4700
-298
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+4700
-298
lines changed

src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Extensions/HttpContextExtensions.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,19 @@ internal static class HttpContextExtensions
66
{
77
public static GraphQLServerOptions? GetGraphQLServerOptions(this HttpContext context)
88
=> context.GetEndpoint()?.Metadata.GetMetadata<GraphQLServerOptions>() ??
9-
(context.Items.TryGetValue(nameof(GraphQLServerOptions), out var o)
10-
&& o is GraphQLServerOptions options
9+
(context.Items.TryGetValue(nameof(GraphQLServerOptions), out var o) && o is GraphQLServerOptions options
1110
? options
1211
: null);
1312

1413
public static GraphQLSocketOptions? GetGraphQLSocketOptions(this HttpContext context)
1514
=> GetGraphQLServerOptions(context)?.Sockets;
1615

17-
public static bool IncludeQueryPlan(this HttpContext context)
16+
public static bool IncludeOperationPlan(this HttpContext context)
1817
{
1918
var headers = context.Request.Headers;
2019

21-
if (headers.TryGetValue(HttpHeaderKeys.QueryPlan, out var values)
22-
&& values.Any(v => v == HttpHeaderValues.IncludeQueryPlan))
20+
if (headers.TryGetValue(HttpHeaderKeys.OperationPlan, out var values)
21+
&& values.Any(v => v == HttpHeaderValues.IncludeOperationPlan))
2322
{
2423
return true;
2524
}

src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/HttpHeaderKeys.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace HotChocolate.AspNetCore;
22

33
internal static class HttpHeaderKeys
44
{
5-
public const string QueryPlan = "GraphQL-Query-Plan";
5+
public const string OperationPlan = "Fusion-Operation-Plan";
66

77
public const string CacheControl = "Cache-Control";
88

src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/HttpHeaderValues.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace HotChocolate.AspNetCore;
22

33
internal static class HttpHeaderValues
44
{
5-
public const string IncludeQueryPlan = "1";
5+
public const string IncludeOperationPlan = "1";
66

77
public const string NoCache = "no-cache";
88

src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Interceptors/DefaultHttpRequestInterceptor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public virtual ValueTask OnCreateAsync(
2727
requestBuilder.TryAddGlobalState(nameof(HttpContext), context);
2828
requestBuilder.TryAddGlobalState(nameof(ClaimsPrincipal), userState.User);
2929

30-
if (context.IncludeQueryPlan())
30+
if (context.IncludeOperationPlan())
3131
{
32-
requestBuilder.TryAddGlobalState(IncludeQueryPlan, true);
32+
requestBuilder.TryAddGlobalState(IncludeOperationPlan, true);
3333
}
3434

3535
if (context.TryGetCostSwitch() is { } costSwitch)

src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Interceptors/DefaultSocketSessionInterceptor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ public virtual ValueTask OnRequestAsync(
3535
requestBuilder.TryAddGlobalState(OperationSessionId, operationSessionId);
3636
requestBuilder.TryAddGlobalState(nameof(ClaimsPrincipal), userState.User);
3737

38-
if (context.IncludeQueryPlan())
38+
if (context.IncludeOperationPlan())
3939
{
40-
requestBuilder.TryAddGlobalState(IncludeQueryPlan, true);
40+
requestBuilder.TryAddGlobalState(IncludeOperationPlan, true);
4141
}
4242

4343
return default;

src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Parsers/DefaultHttpRequestParser.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ internal sealed class DefaultHttpRequestParser : IHttpRequestParser
1616
private const int MinRequestSize = 256;
1717
internal const string QueryIdKey = "id";
1818
private const string OperationNameKey = "operationName";
19+
private const string OnErrorKey = "onError";
1920
internal const string QueryKey = "query";
2021
private const string VariablesKey = "variables";
2122
internal const string ExtensionsKey = "extensions";
@@ -100,6 +101,7 @@ public GraphQLRequest ParseRequestFromParams(IQueryCollection parameters)
100101
string? query = parameters[QueryKey];
101102
string? queryId = parameters[QueryIdKey];
102103
string? operationName = parameters[OperationNameKey];
104+
string? onError = parameters[OnErrorKey];
103105
IReadOnlyDictionary<string, object?>? extensions = null;
104106

105107
// if we have no query or query id, we cannot execute anything.
@@ -155,11 +157,18 @@ public GraphQLRequest ParseRequestFromParams(IQueryCollection parameters)
155157
extensions = ParseJsonObject(se);
156158
}
157159

160+
ErrorHandlingMode? errorHandlingMode = null;
161+
if (!string.IsNullOrEmpty(onError))
162+
{
163+
errorHandlingMode = ParseErrorHandlingMode(onError);
164+
}
165+
158166
return new GraphQLRequest(
159167
document,
160168
queryId,
161169
documentHash,
162170
operationName,
171+
errorHandlingMode,
163172
variableSet,
164173
extensions);
165174
}
@@ -196,11 +205,20 @@ public GraphQLRequest ParsePersistedOperationRequestFromParams(
196205
extensions = ParseJsonObject(se);
197206
}
198207

208+
string? onError = parameters[OnErrorKey];
209+
210+
ErrorHandlingMode? errorHandlingMode = null;
211+
if (!string.IsNullOrEmpty(onError))
212+
{
213+
errorHandlingMode = ParseErrorHandlingMode(onError);
214+
}
215+
199216
return new GraphQLRequest(
200217
null,
201218
operationId,
202219
null,
203220
operationName,
221+
errorHandlingMode,
204222
variableSet,
205223
extensions);
206224
}
@@ -238,6 +256,26 @@ public GraphQLRequest ParsePersistedOperationRequestFromParams(
238256
return (documentHash, document);
239257
}
240258

259+
private ErrorHandlingMode? ParseErrorHandlingMode(string onError)
260+
{
261+
if (onError.Equals("PROPAGATE", StringComparison.OrdinalIgnoreCase))
262+
{
263+
return ErrorHandlingMode.Propagate;
264+
}
265+
266+
if (onError.Equals("NULL", StringComparison.OrdinalIgnoreCase))
267+
{
268+
return ErrorHandlingMode.Null;
269+
}
270+
271+
if (onError.Equals("HALT", StringComparison.OrdinalIgnoreCase))
272+
{
273+
return ErrorHandlingMode.Halt;
274+
}
275+
276+
return null;
277+
}
278+
241279
public IReadOnlyList<GraphQLRequest> ParseRequest(
242280
string sourceText)
243281
{

src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Subscriptions/OperationSession.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ private static OperationRequestBuilder CreateRequestBuilder(GraphQLRequest reque
135135
requestBuilder.SetOperationName(request.OperationName);
136136
}
137137

138+
if (request.ErrorHandlingMode is { } errorHandlingMode)
139+
{
140+
requestBuilder.SetErrorHandlingMode(errorHandlingMode);
141+
}
142+
138143
if (request.DocumentId is not null)
139144
{
140145
requestBuilder.SetDocumentId(request.DocumentId);

src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Subscriptions/WebSocketSession.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ public static async Task AcceptAsync(
4848
connection.ApplicationStopping);
4949
var ct = cts.Token;
5050
var protocol = await connection.TryAcceptConnection();
51-
var interceptor = executorSession.SocketSessionInterceptor;
5251

5352
if (protocol is not null)
5453
{

src/HotChocolate/AspNetCore/src/Transport.Abstractions/HotChocolate.Transport.Abstractions.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
<ItemGroup>
2121
<ProjectReference Include="..\..\..\Language\src\Language.SyntaxTree\HotChocolate.Language.SyntaxTree.csproj" />
22+
<ProjectReference Include="..\..\..\Language\src\Language.Web\HotChocolate.Language.Web.csproj" />
2223
<ProjectReference Include="..\..\..\Utilities\src\Utilities.Buffers\HotChocolate.Utilities.Buffers.csproj" />
2324
</ItemGroup>
2425

src/HotChocolate/AspNetCore/src/Transport.Abstractions/IOperationRequest.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public interface IOperationRequest : IRequestBody
1919
/// </summary>
2020
string? OperationName { get; }
2121

22+
/// <summary>
23+
/// Gets the requested error handling mode.
24+
/// </summary>
25+
ErrorHandlingMode? OnError { get; }
26+
2227
/// <summary>
2328
/// Gets a dictionary containing extension values to include with the operation.
2429
/// </summary>

0 commit comments

Comments
 (0)