2

一部のネットワーク管理操作を自動化する PowerShell ライブラリに取り組んでいます。これらの操作の一部には任意の遅延があり、それぞれが独自の方法で失敗する可能性があります。これらの遅延を適切に処理するために、次の 3 つの主な目的を持つ一般的な再試行関数を作成しています。

  1. 任意のコマンドを実行 (パラメータ付き)
  2. 認識された方法で失敗した場合は、ある程度の制限まで再試行してください
  3. 予期しない方法で失敗した場合は、保釈して報告する

問題は項目 2 です。コマンドに予想される例外の種類を指定できるようにしたいと考えています。PowerShell でこれを行うにはどうすればよいですか?

これが私の機能です:

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)
    do {
        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
        } finally {
            $attempts += 1
        }
    } while ($True -eq $keepTrying)
}

私はそれを次のように呼びます:

$result = Retry-Command -Name = "Foo the bar" -ScriptBlock $cmd -ArgumentList $cmdArgs

しかし、これは結果です:

Retry-Command : Cannot process argument transformation on parameter 'retryException'. 
Cannot convert the "System.Management.Automation.RuntimeException" value of type "System.RuntimeType" to type "System.Exception".
At Foo.ps1:111 char:11
+ $result = Retry-Command <<<<  -Name "Foo the bar" -ScriptBlock $cmd -ArgumentList $cmdArgs
    + CategoryInfo          : InvalidData: (:) [Retry-Command], ParameterBindin...mationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Retry-Command

これは、 の型[System.Management.Automation.RuntimeException]自体が a[System.Exception]ではなく、[System.RuntimeType]意味のある a であると言っているようです。

では、キャッチする例外の種類を指定するにはどうすればよいでしょうか。

4

1 に答える 1

2

変数をキャッチ基準として使用することはできません。型オブジェクト (または何か) でなければなりません。それ以外はすべてエラーになります。回避策は次のようになります。

#You can get the name of the exception using the following (or .Name for just the short name)
#PS > $myerr.Exception.GetType().Fullname
#System.UnauthorizedAccessException


function test {
    param(
    #Validate that specified name is a class that inherits from System.Exception base class
    [ValidateScript({[System.Exception].IsAssignableFrom([type]$_)})]
    $ExceptionType
    )

    try {
        #Test-script, Will throw UnauthorizedAccessException when not run as admin
        (Get-Content C:\test.txt) | % { $_ -replace 'test','lol' } | Set-Content C:\test.txt
    }
    catch [System.Exception] {
        #Check if exceptiontype is equal to the value specified in exceptiontype parameter
        if($_.Exception.GetType() -eq ([type]$ExceptionType)) {
            "Hello. You caught me"
        } else {
        "Uncaught stuff: $($_.Exception.Gettype())"
        }
    }
}

いくつかのテスト。存在しないタイプ、次に非例外タイプ、最後に機能するタイプの 1 つ

PS > test -ExceptionType system.unaut
test : Cannot validate argument on parameter 'ExceptionType'. Cannot convert the "system.unaut" val
ue of type "System.String" to type "System.Type".
At 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'. The "[System.Exception].IsAssignableF
rom([type]$_)" validation script for the argument with value "String" did not return true. Determin
e why the validation script failed and then try the command again.
At line:1 char:21
+ test -ExceptionType String
+                     ~~~~~~
    + CategoryInfo          : InvalidData: (:) [test], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,test


PS > test -ExceptionType UnauthorizedAccessException
Hello. You caught me
于 2013-05-21T06:37:39.920 に答える