Private/Invoke-OriAzExrExceptionRetry.ps1

<#
.DESCRIPTION
This script executing script block, but whenever it throw exception listed in parameter, than it retry the execution. When MaxRetry is reached than it fails.
 
.SYNOPSIS
This script executing script block, but whenever it throw exception listed in parameter, than it retry the execution. When MaxRetry is reached than it fails.
 
.PARAMETER ScriptBlockToRun
Code to execute
 
.PARAMETER ArgumentList
ArgumentList for execution
 
.PARAMETER ListedExceptions
List of execptions where is the reason to retry.
 
.PARAMETER MaxRetry
Max number of retry
 
.PARAMETER SleepTimeInSec
Sleep time in seconds
 
.EXAMPLE
Invoke-ExceptionRetry `
-ScriptBlockToRun {write-host "test"} `
-ListedExceptions @('Timeout','Retray later') `
-MaxRetry 2
 
#>

function Invoke-OriAzExrExceptionRetry {
  [CmdletBinding()]
  param
  (   
    [Parameter(Mandatory = $true, HelpMessage = "Code to execute")]
    [ScriptBlock]$ScriptBlockToRun,

    [Parameter(Mandatory = $false, HelpMessage = "ArgumentList for execution")]
    [Object[]] $ArgumentList,
        
    [Parameter(Mandatory = $false, HelpMessage = "List of execptions where is the reason to retry.")]
    [string[]] $ListedExceptions = @('Timeout'
      , 'The operation has timed out'
      , 'Server was unable to process request'
      , 'Please retry the connection later'
      , 'Internal .Net Framework Data Provider error 6.'),
    
    [Parameter(Mandatory = $false, HelpMessage = "Max number of retry")]
    [string] $MaxRetry = 10,
    
    [Parameter(Mandatory = $false, HelpMessage = "Sleep time in seconds")]
    [string] $SleepTimeInSec = 10
    
  )
      
  #in case of any error we want to stop execution, in stderr having the error. Use try-catch to handle errors if needed.
  $ErrorActionPreference = "Stop";
      
  Write-Debug "-- Invoke-ExceptionRetry --"
    
  $retry = $true
  $retryCount = 0;
  while ($retry) {
    Write-Debug "Try number: $retryCount"
    try {
      $ToReturn = $ScriptBlockToRun.Invoke($ArgumentList);
      $retry = $false
    }
    catch [Exception] {
            
      if (  ![string]::IsNullOrEmpty($_) `
          -and ![string]::IsNullOrEmpty($_.Exception) `
          -and ![string]::IsNullOrEmpty($_.Exception.Message) `
          -and (Test-OriAzExrIsInExceptionList `
            -ListedExceptions $ListedExceptions `
            -ExceptionMessage $_.Exception.Message) `
      ) {
        Write-Warning ($_.Exception | format-list -force | Out-String)
        $retry = $true
        Start-Sleep -Seconds $SleepTimeInSec
      }
      else {
        Write-Error ($_.Exception | format-list -force | Out-String)
        $retry = $false
      }
    }
    $retryCount++;
    if ($retryCount -ge $MaxRetry) {
      throw "Max retry [$MaxRetry] has been reached!"
    }
  }
  Write-Debug "End of processing Invoke-OriAzExrExceptionRetry"
  return $ToReturn
}