Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit e8fcc0e

Browse files
committed
Allow OperationCanceledExceptions to propagate out of ClientWebSocket.ConnectAsync
They're currently being wrapped in WebSocketExceptions, but they should be allowed to escape unwrapped.
1 parent c851f47 commit e8fcc0e

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ public async Task ConnectAsyncCore(Uri uri, CancellationToken cancellationToken,
223223
Abort();
224224
response?.Dispose();
225225

226-
if (exc is WebSocketException)
226+
if (exc is WebSocketException || exc is OperationCanceledException)
227227
{
228228
throw;
229229
}

src/System.Net.WebSockets.Client/tests/ConnectTest.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,5 +267,45 @@ public async Task ConnectAndCloseAsync_UseProxyServer_ExpectedClosedState(Uri se
267267
Assert.Equal(expectedCloseStatusDescription, cws.CloseStatusDescription);
268268
}
269269
}
270+
271+
[ConditionalFact(nameof(WebSocketsSupported))]
272+
[SkipOnTargetFramework(TargetFrameworkMonikers.Uap)]
273+
public async Task ConnectAsync_CancellationRequestedBeforeConnect_ThrowsOperationCanceledException()
274+
{
275+
using (var clientSocket = new ClientWebSocket())
276+
{
277+
var cts = new CancellationTokenSource();
278+
cts.Cancel();
279+
Task t = clientSocket.ConnectAsync(new Uri("ws://" + Guid.NewGuid().ToString("N")), cts.Token);
280+
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
281+
}
282+
}
283+
284+
[ConditionalFact(nameof(WebSocketsSupported))]
285+
[SkipOnTargetFramework(TargetFrameworkMonikers.Uap)]
286+
public async Task ConnectAsync_CancellationRequestedAfterConnect_ThrowsOperationCanceledException()
287+
{
288+
var releaseServer = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
289+
await LoopbackServer.CreateClientAndServerAsync(async uri =>
290+
{
291+
var clientSocket = new ClientWebSocket();
292+
try
293+
{
294+
var cts = new CancellationTokenSource();
295+
Task t = clientSocket.ConnectAsync(uri, cts.Token);
296+
Assert.False(t.IsCompleted);
297+
cts.Cancel();
298+
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
299+
}
300+
finally
301+
{
302+
releaseServer.SetResult(true);
303+
clientSocket.Dispose();
304+
}
305+
}, server => server.AcceptConnectionAsync(async connection =>
306+
{
307+
await releaseServer.Task;
308+
}), new LoopbackServer.Options { WebSocketEndpoint = true });
309+
}
270310
}
271311
}

0 commit comments

Comments
 (0)