diff --git a/Duplicati/CommandLine/ServerUtil/Commands/RunBackup.cs b/Duplicati/CommandLine/ServerUtil/Commands/RunBackup.cs index 79bc1c075..6629e8f5e 100644 --- a/Duplicati/CommandLine/ServerUtil/Commands/RunBackup.cs +++ b/Duplicati/CommandLine/ServerUtil/Commands/RunBackup.cs @@ -67,7 +67,8 @@ public static class RunBackup { if (!quiet) output.AppendConsoleMessage("Waiting for backup to finish..."); - await connection.WaitForBackup(matchingBackup.ID, TimeSpan.FromSeconds(pollinterval), msg => + + await WaitForBackupWithRetries(connection, settings, matchingBackup.ID, pollinterval, output, msg => { if (!quiet) output.AppendConsoleMessage($"[{DateTime.Now}]: {msg}"); @@ -78,4 +79,47 @@ public static class RunBackup } output.SetResult(true); })); + + /// + /// Waits for a backup to finish with retries + /// + /// The connection to use + /// The settings to use + /// The ID of the backup to wait for + /// The interval in seconds to poll for backup status + /// The output interceptor to use + /// The action to perform on each poll + /// A task that represents the asynchronous operation + private static async Task WaitForBackupWithRetries(Connection connection, Settings settings, string backupId, int pollInterval, OutputInterceptor output, Action onPoll) + { + var retry = true; + + while (retry) + { + try + { + await connection.WaitForBackup(backupId, TimeSpan.FromSeconds(pollInterval), onPoll); + return; + } + catch (Exception) + { + retry = false; + try + { + // See if we can get a new connection (re-connect) + onPoll("Re-authenticating..."); + connection = await settings.GetConnection(output); + retry = true; + } + catch (Exception) + { + } + + // Throw original exception if we can't re-connect + if (!retry) + throw; + } + + } while (retry) ; + } }