Skip to content

Commit 287d6cb

Browse files
committed
Abandon Response Formatting Gracefully on Cancellation
1 parent 60d8bc1 commit 287d6cb

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

src/HotChocolate/AspNetCore/src/AspNetCore/Serialization/DefaultHttpResponseFormatter.cs

+17
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,23 @@ public async ValueTask FormatAsync(
168168
throw ThrowHelper.Formatter_InvalidAcceptMediaType();
169169
}
170170

171+
try
172+
{
173+
await FormatInternalAsync(response, result, proposedStatusCode, format, cancellationToken);
174+
}
175+
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
176+
{
177+
// if the request is aborted we will fail gracefully.
178+
}
179+
}
180+
181+
private async ValueTask FormatInternalAsync(
182+
HttpResponse response,
183+
IExecutionResult result,
184+
HttpStatusCode? proposedStatusCode,
185+
FormatInfo format,
186+
CancellationToken cancellationToken)
187+
{
171188
switch (result)
172189
{
173190
case IOperationResult operationResult:

src/HotChocolate/Core/src/Execution/Serialization/EventStreamResultFormatter.cs

+28-7
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,11 @@ private async ValueTask FormatOperationResultAsync(
7474
MessageHelper.WriteNextMessage(_payloadFormatter, operationResult, buffer);
7575
MessageHelper.WriteCompleteMessage(buffer);
7676

77-
await outputStream.WriteAsync(buffer.GetInternalBuffer(), 0, buffer.Length, ct).ConfigureAwait(false);
78-
await outputStream.FlushAsync(ct).ConfigureAwait(false);
77+
if (!ct.IsCancellationRequested)
78+
{
79+
await outputStream.WriteAsync(buffer.GetInternalBuffer(), 0, buffer.Length, ct).ConfigureAwait(false);
80+
await outputStream.FlushAsync(ct).ConfigureAwait(false);
81+
}
7982
}
8083
catch (Exception ex)
8184
{
@@ -111,8 +114,14 @@ private async ValueTask FormatResultBatchAsync(
111114
{
112115
buffer ??= new ArrayWriter();
113116
MessageHelper.WriteNextMessage(_payloadFormatter, operationResult, buffer);
117+
114118
writer.Write(buffer.GetWrittenSpan());
115-
await writer.FlushAsync(ct).ConfigureAwait(false);
119+
120+
if (!ct.IsCancellationRequested)
121+
{
122+
await writer.FlushAsync(ct).ConfigureAwait(false);
123+
}
124+
116125
keepAlive?.Reset();
117126
buffer.Reset();
118127
}
@@ -148,8 +157,11 @@ private async ValueTask FormatResultBatchAsync(
148157
buffer?.Dispose();
149158
}
150159

151-
MessageHelper.WriteCompleteMessage(writer);
152-
await writer.FlushAsync(ct).ConfigureAwait(false);
160+
if (!ct.IsCancellationRequested)
161+
{
162+
MessageHelper.WriteCompleteMessage(writer);
163+
await writer.FlushAsync(ct).ConfigureAwait(false);
164+
}
153165
}
154166

155167
private async ValueTask FormatResponseStreamAsync(
@@ -165,8 +177,11 @@ private async ValueTask FormatResponseStreamAsync(
165177
await formatter.ProcessAsync(ct).ConfigureAwait(false);
166178
}
167179

168-
MessageHelper.WriteCompleteMessage(writer);
169-
await writer.FlushAsync(ct).ConfigureAwait(false);
180+
if (!ct.IsCancellationRequested)
181+
{
182+
MessageHelper.WriteCompleteMessage(writer);
183+
await writer.FlushAsync(ct).ConfigureAwait(false);
184+
}
170185
}
171186

172187
private sealed class StreamFormatter(
@@ -207,6 +222,12 @@ public async Task ProcessAsync(CancellationToken ct)
207222
}
208223
}
209224
}
225+
catch (OperationCanceledException)
226+
{
227+
// if the operation was canceled we do not need to log this
228+
// and will stop gracefully.
229+
return;
230+
}
210231
finally
211232
{
212233
await responseStream.DisposeAsync().ConfigureAwait(false);

0 commit comments

Comments
 (0)