Skip to content

Fix DownloadFile to only log errors when all retries are exhausted#16212

Merged
mmitche merged 2 commits intomainfrom
copilot/fix-download-with-retries-logging
Oct 20, 2025
Merged

Fix DownloadFile to only log errors when all retries are exhausted#16212
mmitche merged 2 commits intomainfrom
copilot/fix-download-with-retries-logging

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Oct 13, 2025

Problem

The DownloadWithRetriesAsync method in DownloadFile.cs was calling Log.LogErrorFromException during retry attempts, even when the download would eventually succeed. This caused MSBuild to mark builds as failed despite successful downloads after retrying.

For example, in https://dev.azure.com/dnceng/internal/_build/results?buildId=2792361, a transient network error was logged as an error:

error : HttpRequestException: No connection could be made because the target machine actively refused it.

The download succeeded on a subsequent retry and produced the expected MSI, but the build was still marked as a failure due to the logged error.

Solution

Moved Log.LogErrorFromException from the retry loop to only execute after all retries are exhausted. Now:

  • During retry attempts: Only informational messages are logged via Log.LogMessage
  • After successful retry: No errors are logged, build succeeds ✅
  • After all retries fail: Error with full stack trace is logged, build fails correctly ❌

Changes

Single line change in src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs:

  • Moved Log.LogErrorFromException(e, true, true, null) from inside the retry loop to inside the if (attempt > Retries) failure block

This ensures errors are only logged when the operation ultimately fails, not during intermediate retry attempts that may succeed.

Fixes the issue originally reported by @mmitche where transient network errors were incorrectly failing builds.

cc: @lewing @joeloff

Original prompt

This section details on the original issue you should resolve

<issue_title>DownloadWithRetriesAsync seems to retry, but still log an error?</issue_title>
<issue_description>Seems to be a retryable exception in https://dev.azure.com/dnceng/internal/_build/results?buildId=2792361&view=logs&j=89eea50f-59b5-5921-c3ce-ce40b36fa819&t=483e1309-93e4-5a7a-74de-93b8d658274f&l=11782

I assume it retried and succeeded since I see the build produce an MSI cc @joeloff

The build was still marked as a failure, most likely because of the logged exception:

Log.LogErrorFromException(e, true, true, null);

Pretty sure that LogError should only be in the return false path. @lewing you added in 025a2b3

 D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error : HttpRequestException: No connection could be made because the target machine actively refused it. (netcorenativeassets.blob.core.windows.net:443)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Http.HttpConnectionPool.InjectNewHttp11ConnectionAsync(QueueItem queueItem)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Http.SocketsHttpHandler.<SendAsync>g__CreateHandlerAndSendAsync|115_0(HttpRequestMessage request, CancellationToken cancellationToken)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at Microsoft.DotNet.Arcade.Sdk.DownloadFile.DownloadWithRetriesAsync(HttpClient httpClient, String uri) in /_/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs:line 184
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error : SocketException: No connection could be made because the target machine actively refused it.
  D:\a\_work\1\s\src\runtime\artifacts\.packages\microsoft.dotnet.build.tasks.installers\11.0.0-beta.25462.113\build\acquisition\acquire-wix\acquire-wix.proj(36,5): error :    at System.Net.Sockets.Socket.AwaitableSocket...

</details>

Fixes dotnet/arcade#16137

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click [here](https://survey3.medallia.com/?EAHeSx-AP01bZqG0Ld9QLQ) to start the survey.

Copilot AI changed the title [WIP] Fix logging behavior for DownloadWithRetriesAsync Fix DownloadFile to only log errors when all retries are exhausted Oct 13, 2025
Copilot AI requested a review from mmitche October 13, 2025 16:56
@akoeplinger akoeplinger marked this pull request as ready for review October 15, 2025 10:04
@mmitche mmitche enabled auto-merge (squash) October 16, 2025 18:35
@mmitche mmitche merged commit 0da9aae into main Oct 20, 2025
10 checks passed
@mmitche mmitche deleted the copilot/fix-download-with-retries-logging branch October 20, 2025 09:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants