PowerShell Try/Catch and Retry

前端 未结 4 2015
故里飘歌
故里飘歌 2020-12-31 07:22

I have a fairly large powershell scripts with many (20+) functions which perform various actions.

Right now all of the code doesn\'t really have any error handling

4条回答
  •  独厮守ぢ
    2020-12-31 07:40

    I adapted @Victor's answer and added:

    • parameter for retries
    • ErrorAction set and restore (or else exceptions do not get caught)
    • exponential backoff delay (I know the OP didn't ask for this, but I use it)
    • got rid of VSCode warnings (i.e. replaced sleep with Start-Sleep)
    # [Solution with passing a delegate into a function instead of script block](https://stackoverflow.com/a/47712807/)
    function Retry()
    {
        param(
            [Parameter(Mandatory=$true)][Action]$action,
            [Parameter(Mandatory=$false)][int]$maxAttempts = 3
        )
    
        $attempts=1    
        $ErrorActionPreferenceToRestore = $ErrorActionPreference
        $ErrorActionPreference = "Stop"
    
        do
        {
            try
            {
                $action.Invoke();
                break;
            }
            catch [Exception]
            {
                Write-Host $_.Exception.Message
            }
    
            # exponential backoff delay
            $attempts++
            if ($attempts -le $maxAttempts) {
                $retryDelaySeconds = [math]::Pow(2, $attempts)
                $retryDelaySeconds = $retryDelaySeconds - 1  # Exponential Backoff Max == (2^n)-1
                Write-Host("Action failed. Waiting " + $retryDelaySeconds + " seconds before attempt " + $attempts + " of " + $maxAttempts + ".")
                Start-Sleep $retryDelaySeconds 
            }
            else {
                $ErrorActionPreference = $ErrorActionPreferenceToRestore
                Write-Error $_.Exception.Message
            }
        } while ($attempts -le $maxAttempts)
        $ErrorActionPreference = $ErrorActionPreferenceToRestore
    }
    
    # function MyFunction($inputArg)
    # {
    #     Throw $inputArg
    # }
    
    # #Example of a call:
    # Retry({MyFunction "Oh no! It happened again!"})
    # Retry {MyFunction "Oh no! It happened again!"} -maxAttempts 10
    

提交回复
热议问题