Catching dynamic exception types in PowerShell -
i'm working on powershell library automates network management operations. of these operations have arbitrary delays, , each can fail in unique ways. handle these delays gracefully, i'm creating generic retry function has 3 main purposes:
- execute arbitrary command (with parameters)
- if fails in recognized way, try again, limit
- if fails in unexpected way, bail , report
the problem item #2. want able specify expected exception type command. how can in powershell?
here's function:
function retry-command { [cmdletbinding()] param( [parameter(mandatory=$true, position=0)] [string] $name, [parameter(mandatory=$true, position=1)] [string] $scriptblock, [string[]] $argumentlist, [int] $maxattempts=3, [int] $retryseconds=10, [system.exception] $retryexception=[system.management.automation.runtimeexception] ) $attempts = 1 $keeptrying = $true $cmd = [scriptblock]::create($scriptblock) { try { &$cmd @argumentlist $keeptrying = $false write-verbose "command [$commandname] succeeded after $attmpts attempts." } catch [$retryexception] { $msg = "command [$commandname] failed. attempt $attempts of $maxattempts." write-verbose $msg; if ($maxattempts -gt $attempts) { write-debug "sleeping $retryseconds" start-sleep -seconds $retryseconds } else { $keeptrying = $false write-debug "reached $attempts attempts. re-raising exception." throw $_.exception } } catch [system.exception] { $keeptrying = $false $msg = "unexpected exception while executing command [$commandname]: " write-error $msg + $_.exception.tostring() throw $_.exception } { $attempts += 1 } } while ($true -eq $keeptrying) }
i call this:
$result = retry-command -name = "foo bar" -scriptblock $cmd -argumentlist $cmdargs
but result:
retry-command : cannot process argument transformation on parameter 'retryexception'. cannot convert "system.management.automation.runtimeexception" value of type "system.runtimetype" type "system.exception". @ foo.ps1:111 char:11 + $result = retry-command <<<< -name "foo bar" -scriptblock $cmd -argumentlist $cmdargs + categoryinfo : invaliddata: (:) [retry-command], parameterbindin...mationexception + fullyqualifiederrorid : parameterargumenttransformationerror,retry-command
this seems saying type of [system.management.automation.runtimeexception]
not [system.exception]
, instead [system.runtimetype]
makes sense.
so, how specify type of exception caught?
it's not possible use variable catch criteria, has type-object (or something), else gives error. workaround this:
#you can name of exception using following (or .name short name) #ps > $myerr.exception.gettype().fullname #system.unauthorizedaccessexception function test { param( #validate specified name class inherits system.exception base class [validatescript({[system.exception].isassignablefrom([type]$_)})] $exceptiontype ) try { #test-script, throw unauthorizedaccessexception when not run admin (get-content c:\test.txt) | % { $_ -replace 'test','lol' } | set-content c:\test.txt } catch [system.exception] { #check if exceptiontype equal value specified in exceptiontype parameter if($_.exception.gettype() -eq ([type]$exceptiontype)) { "hello. caught me" } else { "uncaught stuff: $($_.exception.gettype())" } } }
a few tests. 1 non-existing type, non-exception type, , working one
ps > test -exceptiontype system.unaut test : cannot validate argument on parameter 'exceptiontype'. cannot convert "system.unaut" val ue of type "system.string" type "system.type". @ line:1 char:21 + test -exceptiontype system.unaut + ~~~~~~~~~~~~ + categoryinfo : invaliddata: (:) [test], parameterbindingvalidationexception + fullyqualifiederrorid : parameterargumentvalidationerror,test ps > test -exceptiontype string test : cannot validate argument on parameter 'exceptiontype'. "[system.exception].isassignablef rom([type]$_)" validation script argument value "string" did not return true. determin e why validation script failed , try command again. @ line:1 char:21 + test -exceptiontype string + ~~~~~~ + categoryinfo : invaliddata: (:) [test], parameterbindingvalidationexception + fullyqualifiederrorid : parameterargumentvalidationerror,test ps > test -exceptiontype unauthorizedaccessexception hello. caught me
Comments
Post a Comment