Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSocketException when browser.CloseAsync is called on Visual Studio 2022 and .NET7+ debugging #2374

Open
eMuonTau opened this issue Dec 11, 2023 · 3 comments

Comments

@eMuonTau
Copy link

Description

Visual Studio 2022 breaks on an unhandled WebSocketException when browser.CloseAsync() is called. This only happens on .NET 8. When using .NET 6 there is no exception. I got same exception a few times with .NET 7 but i couldn't reproduce it again. On .NET 8 it happens every time.

Looks like you can continue when this exception is thrown and there is no exception if debugger is not attached. If it is related to Visual Studio please let me know.

System.Net.WebSockets.WebSocketException: 'The remote party closed the WebSocket connection without completing the close handshake.'

   at System.Net.WebSockets.ManagedWebSocket.ThrowEOFUnexpected()
   at System.Net.WebSockets.ManagedWebSocket.<EnsureBufferContainsAsync>d__74.MoveNext()
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) in /_/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/PoolingAsyncValueTaskMethodBuilderT.cs:line 435
   at System.Net.WebSockets.ManagedWebSocket.<ReceiveAsyncPrivate>d__63`1.MoveNext()

Complete minimal example reproducing the issue

using System;
using System.IO;
using System.Threading.Tasks;
using PuppeteerSharp;

namespace Namespace;

static class Program
{
  static async Task Main() {
    using var browserFetcher = new BrowserFetcher();
    await browserFetcher.DownloadAsync();
    var browser = await Puppeteer.LaunchAsync(new LaunchOptions() {
      Headless = true,
      UserDataDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ".puppeteer", "chrome")
    });

    try {
      var page = await browser.NewPageAsync();
      await page.GoToAsync("https://google.com");
      await browser.CloseAsync();
    } catch (Exception ex) {
      // WebSocketException is not caught here
      // throw;
    }
    Console.WriteLine("END");
    Console.ReadLine();
  }
}

Expected behavior:

It should not throw an exception.

Actual behavior:

Debugging breaks on WebSocketException when browser.CloseAsync() is called.

Call Stack

[Exception] System.Net.WebSockets.dll!System.Net.WebSockets.ManagedWebSocket.ThrowEOFUnexpected()
[Exception] System.Net.WebSockets.dll!System.Net.WebSockets.ManagedWebSocket.EnsureBufferContainsAsync(int minimumRequiredBytes, System.Threading.CancellationToken cancellationToken)
System.Private.CoreLib.dll!System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() Line 53
System.Private.CoreLib.dll!System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<System.Threading.Tasks.VoidTaskResult>.ThrowForFailedGetResult(short token) Line 109
System.Private.CoreLib.dll!System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<System.Threading.Tasks.VoidTaskResult>.GetResult(short token) Line 95
System.Private.CoreLib.dll!System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder<System.Threading.Tasks.VoidTaskResult>.StateMachineBox<System.Runtime.CompilerServices.IAsyncStateMachine>.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(short token) Line 435
System.Net.WebSockets.dll!System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate<System.Net.WebSockets.WebSocketReceiveResult>(System.Memory<byte> payloadBuffer, System.Threading.CancellationToken cancellationToken)
System.Net.WebSockets.dll!System.Net.WebSockets.ManagedWebSocket.ReceiveAsync(System.ArraySegment<byte> buffer, System.Threading.CancellationToken cancellationToken)
PuppeteerSharp.dll!PuppeteerSharp.Transport.WebSocketTransport.GetResponseAsync(System.Threading.CancellationToken cancellationToken) Line 163
[Resuming Async Method]	
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.AsyncStateMachineBox<PuppeteerSharp.Transport.WebSocketTransport.<GetResponseAsync>d__25>.ExecutionContextCallback(object s) Line 287
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 183
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.AsyncStateMachineBox<PuppeteerSharp.Transport.WebSocketTransport.<GetResponseAsync>d__25>.MoveNext(System.Threading.Thread threadPoolThread) Line 324
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.AsyncStateMachineBox<PuppeteerSharp.Transport.WebSocketTransport.<GetResponseAsync>d__25>.MoveNext() Line 302
System.Private.CoreLib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__12_0(System.Action innerContinuation, System.Threading.Tasks.Task innerTask) Line 301
System.Private.CoreLib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining) Line 743
System.Private.CoreLib.dll!System.Threading.Tasks.Task.RunContinuations(object continuationObject) Line 3417
System.Private.CoreLib.dll!System.Threading.Tasks.Task<System.__Canon>.TrySetResult(System.__Canon result) Line 401
System.Private.CoreLib.dll!System.Threading.Tasks.ValueTask<System.Net.WebSockets.WebSocketReceiveResult>.ValueTaskSourceAsTask..cctor.AnonymousMethod__4_0(object state) Line 649
System.Net.WebSockets.dll!System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate<System.Net.WebSockets.WebSocketReceiveResult>(System.Memory<byte> payloadBuffer, System.Threading.CancellationToken cancellationToken)
[Resuming Async Method]	
System.Private.CoreLib.dll!System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder<System.Net.WebSockets.WebSocketReceiveResult>.StateMachineBox<System.Net.WebSockets.ManagedWebSocket.<ReceiveAsyncPrivate>d__63<System.Net.WebSockets.WebSocketReceiveResult>>.ExecutionContextCallback(object s) Line 393
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 183
System.Private.CoreLib.dll!System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder<System.Net.WebSockets.WebSocketReceiveResult>.StateMachineBox<System.Net.WebSockets.ManagedWebSocket.<ReceiveAsyncPrivate>d__63<System.Net.WebSockets.WebSocketReceiveResult>>.MoveNext() Line 415
System.Private.CoreLib.dll!System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder.SetResult() Line 51
System.Net.WebSockets.dll!System.Net.WebSockets.ManagedWebSocket.EnsureBufferContainsAsync(int minimumRequiredBytes, System.Threading.CancellationToken cancellationToken)
[Resuming Async Method]	
System.Private.CoreLib.dll!System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder<System.Threading.Tasks.VoidTaskResult>.StateMachineBox<System.Net.WebSockets.ManagedWebSocket.<EnsureBufferContainsAsync>d__74>.ExecutionContextCallback(object s) Line 393
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 183
System.Private.CoreLib.dll!System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder<System.Threading.Tasks.VoidTaskResult>.StateMachineBox<System.Net.WebSockets.ManagedWebSocket.<EnsureBufferContainsAsync>d__74>.MoveNext() Line 415
System.Private.CoreLib.dll!System.IO.Stream.ReadAtLeastAsyncCore(System.Memory<byte> buffer, int minimumBytes, bool throwOnEndOfStream, System.Threading.CancellationToken cancellationToken) Line 450
[Resuming Async Method]	
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 183
System.Private.CoreLib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__12_0(System.Action innerContinuation, System.Threading.Tasks.Task innerTask) Line 301
System.Private.CoreLib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining) Line 743
System.Private.CoreLib.dll!System.Threading.Tasks.Task.RunContinuations(object continuationObject) Line 3417
System.Private.CoreLib.dll!System.Threading.Tasks.Task<int>.TrySetResult(int result) Line 401
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetExistingTaskResult(System.Threading.Tasks.Task<int> task, int result) Line 446
[Completed] System.Net.Http.dll!System.Net.Http.HttpConnection.RawConnectionStream.ReadAsync(System.Memory<byte> buffer, System.Threading.CancellationToken cancellationToken) Line 88
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AsyncStateMachineBox<System.Net.Http.HttpConnection.RawConnectionStream.<ReadAsync>d__6>.ExecutionContextCallback(object s) Line 287
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 183
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AsyncStateMachineBox<System.Net.Http.HttpConnection.RawConnectionStream.<ReadAsync>d__6>.MoveNext(System.Threading.Thread threadPoolThread) Line 324
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AsyncStateMachineBox<System.Net.Http.HttpConnection.RawConnectionStream.<ReadAsync>d__6>.MoveNext() Line 302
System.Private.CoreLib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__12_0(System.Action innerContinuation, System.Threading.Tasks.Task innerTask) Line 301
System.Private.CoreLib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining) Line 743
System.Private.CoreLib.dll!System.Threading.Tasks.Task.RunContinuations(object continuationObject) Line 3417
System.Private.CoreLib.dll!System.Threading.Tasks.Task<int>.TrySetResult(int result) Line 401
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetExistingTaskResult(System.Threading.Tasks.Task<int> task, int result) Line 446
[Completed] System.Net.Http.dll!System.Net.Http.HttpConnection.ReadBufferedAsyncCore(System.Memory<byte> destination) Line 1877
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AsyncStateMachineBox<System.Net.Http.HttpConnection.<ReadBufferedAsyncCore>d__105>.ExecutionContextCallback(object s) Line 287
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 183
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AsyncStateMachineBox<System.Net.Http.HttpConnection.<ReadBufferedAsyncCore>d__105>.MoveNext(System.Threading.Thread threadPoolThread) Line 324
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AsyncStateMachineBox<System.Net.Http.HttpConnection.<ReadBufferedAsyncCore>d__105>.MoveNext() Line 302
System.Net.Sockets.dll!System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.InvokeContinuation(System.Action<object> continuation, object state, bool forceAsync, bool requiresExecutionContextFlow)
System.Net.Sockets.dll!System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.OnCompleted(System.Net.Sockets.SocketAsyncEventArgs _)
System.Net.Sockets.dll!System.Net.Sockets.SocketAsyncEventArgs..cctor.AnonymousMethod__176_0(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* nativeOverlapped)
System.Private.CoreLib.dll!System.Threading.PortableThreadPool.IOCompletionPoller.Callback.Invoke(System.Threading.PortableThreadPool.IOCompletionPoller.Event e) Line 265
System.Private.CoreLib.dll!System.Threading.ThreadPoolTypedWorkItemQueue<System.Threading.PortableThreadPool.IOCompletionPoller.Event, System.Threading.PortableThreadPool.IOCompletionPoller.Callback>.System.Threading.IThreadPoolWorkItem.Execute() Line 1143
System.Private.CoreLib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 924
System.Private.CoreLib.dll!System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() Line 121

Versions

  • PuppeteerSharp: 9.1.0 - 13.0.2
  • .NET: 8.0
  • Visual Studio 2022: 17.8.3
@kblok
Copy link
Member

kblok commented Dec 11, 2023

@eMuonTau
Copy link
Author

Do you have VS set to break on all exceptions? That piece of code has a try/catch.

Exception Settings are on default. WebSocketException is not even selected in CLR Exceptions and dialog indicates to break only when user-unhandled.

2023-12-12_01h31_17

@kblok
Copy link
Member

kblok commented Dec 12, 2023

@eMuonTau I think the issue is with the second checkbox you have there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants