From 9e543ab4d66d3beb9c8dcaf377342e0fc9cb54a8 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 8 Jul 2026 12:15:24 -0600 Subject: [PATCH] Retry file operations on access denied errors This should improve resiliency in cloudbuilds where multiple top-level builds are executed in the same repo concurrently (naughty). --- src/Shared/Utilities.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Shared/Utilities.cs b/src/Shared/Utilities.cs index 8207acdfd..f037d4d07 100644 --- a/src/Shared/Utilities.cs +++ b/src/Shared/Utilities.cs @@ -7,7 +7,8 @@ namespace Nerdbank.GitVersioning; internal static class Utilities { - private const int ProcessCannotAccessFileHR = unchecked((int)0x80070020); + private const int SharingViolation = unchecked((int)0x80070020); // ERROR_SHARING_VIOLATION + private const int AccessDenied = unchecked((int)0x80070005); // ERROR_ACCESS_DENIED internal static void FileOperationWithRetry(Action operation) { @@ -20,11 +21,15 @@ internal static void FileOperationWithRetry(Action operation) operation(); break; } - catch (IOException ex) when (ex.HResult == ProcessCannotAccessFileHR && retriesLeft > 0) + catch (Exception ex) when (IsTransientFileAccessError(ex) && retriesLeft > 1) { - Task.Delay(100).Wait(); + Thread.Sleep(100); continue; } } } + + private static bool IsTransientFileAccessError(Exception ex) => ex is + IOException { HResult: SharingViolation } or + UnauthorizedAccessException { HResult: AccessDenied }; }