Skip to content

Ensure stacktrace is always present for ValueTask.FromException in Networking libs #117652

@jogibear9988

Description

@jogibear9988

UPD 2025-07-17 by @CarnaViire

There are cases where we don't assign a stacktrace to an exception when using ValueTask.FromException, i.e. instead of

return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new SomeException()));

we do just

return ValueTask.FromException(new SomeException());

In general, ExceptionDispatchInfo.SetCurrentStackTrace usage seems inconsistent across Networking libs -- with both ways (assigning and not assigning a stacktrace) sometimes even present within a single file (see #117652 (comment)).

We should make this consistent, and always include the stacktrace (the missing stacktrace makes debugging harder -- the original report below is a good example).


Original report by @jogibear9988

Description

I've the following code:

    public async Task SendAsync(byte[] message, WebSocketMessageType messageType, CancellationToken ct)
    {
        try
        {
            if (webSocket.State == WebSocketState.Open)
            {
                await webSocket.SendAsync(new ArraySegment<byte>(message, 0, message.Length), messageType, true, ct);
            }
        }
        catch (Exception ex)
        {
            logger.Error("SendAsync()", ex);
        }
    }

where websocket is an object of System.Net.WebSockets.WebSocket

Now I got 100reds of Messages like this in my log:

    SendAsync() - WebSocketException The remote party closed the WebSocket connection without completing the close handshake.
       at async Task MCC.HttpWebsocketServer.WebsocketConnection.SendAsync(byte[] message, WebSocketMessageType messageType, CancellationToken ct) in C:/BuildAgent/work/fd2044180b81ae6e/MCC.V1.0/6Utilities/MCC.HttpWebsocketServer/WebsocketConnection.cs:line 46Void Throw()
    ObjectDisposedException Cannot write to the response body, the response has completed.
    Object name: 'HttpResponseStream'.    at void Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponsePipeWriter.ValidateState(CancellationToken cancellationToken)+ThrowObjectDisposedException()
       at ValueTask System.Net.WebSockets.ManagedWebSocket.SendFrameLockAcquiredNonCancelableAsync(MessageOpcode opcode, bool endOfMessage, bool disableCompression, ReadOnlyMemory<byte> payloadBuffer)

How could that happen? Who is triggering the Send, why do I not see it in my StackTrace?

Reproduction Steps

.

Expected behavior

.

Actual behavior

.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions