dotnet / dotnet/runtime

[wasm][browser] BrowserHttpHandler_StreamingRequest_Http1Fails throws TaskCanceledException instead of HttpRequestException

Open
#129,758 2 comments 0 reactions 0 assignees View on GitHub
arch-wasm area-System.Net.Http
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

## Description

`System.Net.Http.Functional.Tests.SocketsHttpHandler_ResponseStreamTest.BrowserHttpHandler_StreamingRequest_Http1Fails` (source: `src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs`) fails on **Browser + CoreCLR (wasm)** but passes on **Browser + Mono (wasm)**.

The test sends a streaming (`WebAssemblyEnableStreamingRequest`) POST over HTTP/1 and expects the browser `fetch` to reject it quickly:

```csharp
HttpRequestException ex = await Assert.ThrowsAsync(() => client.SendAsync(req));
Assert.Equal("TypeError: Failed to fetch", ex.Message);
```

On CoreCLR-wasm the request instead hangs and is canceled by the 100s `HttpClient.Timeout`:

```
Assert.Throws() Failure: Exception type was not an exact match
Expected: typeof(System.Net.Http.HttpRequestException)
Actual: typeof(System.Threading.Tasks.TaskCanceledException)
---- System.Threading.Tasks.TaskCanceledException : The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing.
-------- System.TimeoutException : The operation was canceled.
------------ System.Threading.Tasks.TaskCanceledException : The operation was canceled.
---------------- System.Runtime.InteropServices.JavaScript.JSException : Error: OperationCanceledException
at System.Net.Http.BrowserHttpInterop.CancellationHelper(Task promise, CancellationToken cancellationToken, JSObject jsController)
```

This indicates the streaming-request-over-HTTP/1 rejection path that produces `TypeError: Failed to fetch` is not being hit on CoreCLR-wasm (the request appears to proceed instead of failing fast).

## How it was found

Discovered while bringing up the new scheduled **Browser + CoreCLR** outerloop libraries-test lane (#129436). This `[OuterLoop]` browser test had never run in CI before (Mono runs innerloop only).

## Workaround

The test is being gated to skip on CoreCLR-wasm only, keeping Mono-wasm coverage:

```csharp
[ActiveIssue("https://github.com/dotnet/runtime/issues/", typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime))]
```

(The test is already `[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))]`, so the `ActiveIssue` only takes effect on Browser + CoreCLR.)

> [!NOTE]
> This issue was created by GitHub Copilot on behalf of the user.

Contributor guide

Open the contributing guide

Research direction

Start with src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs and run Browser + CoreCLR wasm test SocketsHttpHandler_ResponseStreamTest.BrowserHttpHandler_StreamingRequest_Http1Fails. Trace the BrowserHttpInterop.CancellationHelper path and compare Browser + CoreCLR with Browser + Mono behavior. Done means the streaming HTTP/1 request fails promptly with HttpRequestException and the expected "TypeError: Failed to fetch" message instead of timing out.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, wasm
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.