Introduction
Often it is required to retry some logic in the program, for example, when making flaky network or web request which is not reliable. Things may fail a few times, but that doesn’t mean there was a problem, and if your program throws an error and flow of control proceeds to the next line you may see unexpected results. I think it is wise to build some sort of a retry logic to handle such scenarios that make sure some commands are run more than once. So in this blog post, we will discuss a simple function I’ve created to implement retry logic.
Let’s keep a few things in our minds before writing a retry logic:
-
- We have to iterate the same piece of the program.
I’ll use some sort of loop for that, likefor
,while
, ordo..while
. - When some program fails it may throw some error.
Try..catch block can be employed to catch such errors - Errors can be a Terminating or Non-Terminating but Try..Catch block will work only with the Terminating errors.
The automatic variable$ErrorActionPreference
needs to be set asStop
to make sure errors thrown by the target code are all Terminating errors. - Put the retry logic in a function that accepts as
[scriptsblock]
input and supports custom success and failure messages.
No Specific reason to use [ScriptBlocks], I could have used command input as strings or files. - All intermediate steps and retries must go to Verbose stream so that it can be enabled or disabled using the
-Verbose
switch.
It is not necessary to output the retry logic in action, and you can suppress any output and run the logic in the background. - Add the Error message in the verbose output.
For this, we can access the value of$_.exception.message
in the catch block - The output of the commands defined in the script block must return to the console unless explicitly suppressed in Scriptblock by the user.
- We have to iterate the same piece of the program.
Function
Examples
Retry-Command
cmdlet will attempt to execute connectivity test 3 times. By default 3 retry attempts are made at every 30 seconds and you have to explicitly define the Verbose
switch to see the retry logic in action.We can even customize the number of retry attempts and timeout time in seconds using the parameters: -RetryCount
and -TimeoutInSecs
respectively.
In some scenarios, you may want the retry logic to be triggered when you don’t get the desired output. Such use cases can implement the retry logic of the Retry-Command
function, by throwing an error throw()
in your script block that will be executed.
You can even define some conditional statements and throw()
custom errors or use the Write-Error
cmdlet to throw an error and trigger the retry.
The function is also capable of handling scriptblocks as input through the pipeline.
Prateek Singh
Related posts
2 Comments
Leave a ReplyCancel reply
Categories
Author of Books
Awards
Open Sourced Projects
Author at
Blog Roll
Mike F RobbinsDamien Van Robaeys
Stéphane van Gulick
Kevin Marquette
Adam Bertram
Stephanos Constantinou
Francois-Xavier Cat
Ravikanth Chaganti
Roman Levchenko
Blog Stats
- 1,131,939 People Reached
Nice job!
Just a couple of comments:
1) For extra clarity “TimeoutInSecs” might be renamed to “DelayInSecs”.
2) The “Result” in “Invoke-Command -ScriptBlock $ScriptBlock -OutVariable Result” doesn’t seem to be used. Btw, I wonder if it might be useful to have “Invoke-Command -ScriptBlock $ScriptBlock -ErrorAction Stop”
Hello, this doesn’t work at all. Anything I tried would just not work and show the failed messages.