Open mdemler opened 6 months ago
When running the same code under Android, receiving a WebException instead.
That's confusing to me, as WebException is part of System.Net.Requests, which HttpClient in .NET Core doesn't use at all; WebRequest is built on top of HttpClient, not the other way around.
Can you share the full stack trace from the exception you're receiving?
Is it possible you're actually running on the old mono (https://github.com/mono/mono) rather than on .NET 8?
Ah, this might be coming from the Mono.Android HttpClientHandler that gets substituted in on Android (and which is not part of this repo). @steveisok ?
@simonrozsival, is that expected behavior from the Android handler?
When running the same code under Android, receiving a WebException instead.
That's confusing to me, as WebException is part of System.Net.Requests, which HttpClient in .NET Core doesn't use at all; WebRequest is built on top of HttpClient, not the other way around.
Can you share the full stack trace from the exception you're receiving?
Is it possible you're actually running on the old mono (https://github.com/mono/mono) rather than on .NET 8?
Updated my posting for that. Sorry, should have included that to begin with.
@mdemler if you put <UseNativeHttpHandler>false</UseNativeHttpHandler>
in your project, that'll use SocketsHttpHandler and you should have similar behavior as you do on Windows.
Thanks, @steveisok! I've done that, and that will work for us for what we're trying to handle now. It would be nice if this worked as expected even when using the native handler though. Thanks again.
It's a known issue: https://github.com/xamarin/xamarin-android/issues/5761
@grendello do you know why we haven't changed the exceptions to HttpRequestException
yet?
@simonrozsival IIRC it was backward compatibility with classic. Shouldn't be an issue anymore
The right time to change this behaviour was when going from Xamarin to Core. It's shameful that this wasn't done then. My other issue, linked above, was opened more than three years ago and nobody seems to care that impossible exceptions are being thrown from within the framework.
Description
When running on Windows, TaskCanceledException is being thrown by async HttpClient calls when the timeout elapses. When running the same code under Android, receiving a WebException instead.
Reproduction Steps
` using var client = new HttpClient();
`
Expected behavior
Behavior is identical between Windows and Android. TaskCanceledException is thrown for both.
Actual behavior
WebException is thrown when a timeout is reached.
{System.Net.WebException: Socket closed ---> Java.Net.SocketException: Socket closed at Java.Interop.JniEnvironment.InstanceMethods.CallIntMethod(JniObjectReference instance, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:line 20203 at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualInt32Method(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 511 at Java.Net.HttpURLConnection.get_ResponseCode() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Java.Net.HttpURLConnection.cs:line 521 at Xamarin.Android.Net.AndroidMessageHandler.<>c__DisplayClass136_0.<DoProcessRequest>b__2() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 625 at System.Threading.Tasks.Task
1[[System.Net.HttpStatusCode, System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].InnerInvoke() at System.Threading.Tasks.Task.<>c.<.cctor>b__281_0(Object obj) at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) --- End of stack trace from previous location --- at Xamarin.Android.Net.AndroidMessageHandler.DoProcessRequest(HttpRequestMessage request, URL javaUrl, HttpURLConnection httpConnection, CancellationToken cancellationToken, RequestRedirectionState redirectState) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 625 at Xamarin.Android.Net.AndroidMessageHandler.DoSendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 456 --- End of managed Java.Net.SocketException stack trace --- java.net.SocketException: Socket closed at java.net.SocketInputStream.read(SocketInputStream.java:188) at java.net.SocketInputStream.read(SocketInputStream.java:143) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797) at com.android.okhttp.okio.Okio$2.read(Okio.java:138) at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213) at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:307) at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:301) at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:197) at com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:188) at com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:129) at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:750) at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542) at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106) at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)--- End of managed Java.Net.SocketException stack trace --- java.net.SocketException: Socket closed at java.net.SocketInputStream.read(SocketInputStream.java:188) at java.net.SocketInputStream.read(SocketInputStream.java:143) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824) at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797) at com.android.okhttp.okio.Okio$2.read(Okio.java:138) at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213) at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:307) at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:301) at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:197) at com.android.okhttp.internal.http.Http1xStream.readResponse(Http1xStream.java:188) at com.android.okhttp.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:129) at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:750) at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542) at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106) at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
--- End of inner exception stack trace --- at Xamarin.Android.Net.AndroidMessageHandler.DoSendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 471 at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at MauiApp4.MainPage.RunTestAsync() in C:\Projects\Temp\MauiApp4\MauiApp4\MainPage.xaml.cs:line 41}
`
Regression?
Not sure. This is new code.
Known Workarounds
Unknown. Defeats the ability to use Polly to retry on a timeout.
Configuration
.NET 8.0.200
Windows 11.
Device: SAMSUNG A9+, Android 13. Same behavior on Emulator running Android 13.
Other information
No response