Repository navigation
Fix AndroidMessageHandler upload I/O exception translation - #13125
simonrozsival wants to merge 2 commits into
Conversation
Preserve cancellation and the legacy WebException exception chain. Add repeated loopback upload-reset and content-source failure coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The implementation and regression coverage are sound; only a non-blocking namespace convention suggestion remains.
1 open finding
What changed in this PR
Fixes upload I/O exception translation in AndroidMessageHandler, aligning failures with the HttpClient contract.
Changes:
- Translates managed upload
IOExceptionfailures intoHttpRequestException. - Adds loopback regression coverage for resets, exception chains, cancellation, and stream rewind.
- Adds focused exception-test categories.
| File | Description |
|---|---|
AndroidMessageHandler.cs |
Translates upload I/O failures. |
AndroidMessageHandlerUploadTests.cs |
Adds upload failure regression tests. |
AndroidMessageHandlerTests.cs |
Categorizes existing exception tests. |
Mono.Android.NET-Tests.csproj |
Includes the new test file. |
🧠 Review effort: Balanced
|
/review |
|
✅ Android PR Reviewer completed successfully! Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "azcliprod.blob.core.windows.net"See Network Configuration for more information.
|
There was a problem hiding this comment.
Review summary
Verdict: ❌ Reject — 1 error, 0 warnings, 0 suggestions
The new catch correctly translates copy-time managed I/O failures while preserving cancellation precedence and the compatibility WebException chain. However, the equivalent I/O failure path from HttpContent.ReadAsStreamAsync() remains outside the translation boundary, so the SendAsync exception contract is still incomplete; details and a regression-test request are inline.
CI was still in progress when reviewed: 38 of 42 checks had completed successfully, with three emulator lanes running and the aggregate check queued; no failures were reported.
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
azcliprod.blob.core.windows.net
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "azcliprod.blob.core.windows.net"See Network Configuration for more information.
Generated by Android PR Reviewer for #13125 · copilot · gpt56 · 108.4 AIC · ⌖ 11.2 AIC · ⊞ 26.4K
Comment /review to run again
Include ReadAsStreamAsync in the existing cancellation and I/O exception translation boundary, and only rewind an acquired stream. Exercise acquisition and copy failures, application exceptions, cancellation precedence, and rewind in regression tests. Use a file-scoped namespace for the new fixture. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Fixes #12934's upload exception-contract failure. The TLS performance concern remains separate; measurements are attached to the issue. This PR makes no TLS or default-handler changes.
OutputStreamInvokerwraps Java transport failures in managedIOException, bypassing the handler's Java-only exception translation. Translate managed I/O failures during request-body copying using the existing compatibility helper. Cancellation handling runs first, the original exception chain is retained, seekable streams are rewound, and unrelated application exceptions remain unchanged.Adds repeated loopback upload-reset coverage for both completion options, asserting the exception chain, uncancelled caller token, and rewind. Also tests content-source I/O/non-I/O failures and enables focused execution of existing connection/redirect tests.
Validation
Release, physical Samsung SM-A165F, API 36, arm64. Current checkout targets
net11.0-androidbut pins runtime12.0.0-alpha.1.26509.101; the reporter's exact .NET 11 RC package and x86_64/Mono/NativeAOT configurations were not tested.make prepare CONFIGURATION=Release && make all CONFIGURATION=Release— preparation passed; initial build failed on missing extra API reference assemblies../dotnet-local.sh build Microsoft.Android.slnx -c Release -t:BuildExtraApiLevels -v:q— passed; subsequentmake all CONFIGURATION=Releasepassed../dotnet-local.sh build -t:ConfigureLocalWorkload -c Release build-tools/create-packs/Microsoft.Android.Sdk.proj -v:q— passed.make all CONFIGURATION=Release— passed, 0 warnings/errors.git diff --check— passed.Final install — passed, 0 errors, 38 existing analysis/trimming warnings:
Final device run — 16 passed, 0 failed, 0 skipped:
Before/after proof: temporarily removing only the production catch, rebuilding, and running the upload category produced 3 failures in 4 cases: both resets and source
IOExceptionfailed; unrelated application-exception propagation passed. Restoring the catch and rebuilding produced the passing final run. NUnit counts each three-repeat reset as one case.