考慮してください:
Invoke-WebRequest $sumoApiURL -Headers @{"Content-Type"= "application/json"} -Credential $cred -WebSession $webRequestSession -Method post -Body $sumojson -ErrorAction Stop
これにより、次の例外がスローされます。
どうすればそれを完全にキャッチできますか、少なくとも「同じ名前のリソースがすでに存在している」を除外できますか?
$_.Exception.GetType().FullName
を使用すると、
System.Net.WebException
そして$_.Exception.Message
は
リモートサーバーがエラーを返しました:(400)Bad Request。
PowerShellのエラーと例外は構造化オブジェクトです。コンソールに表示されるエラーメッセージは、実際にはエラー/例外オブジェクトのいくつかの要素からの情報を含むフォーマットされたメッセージです。次のように自分で(再)構築できます:
$formatstring = "{0} : {1}`n{2}`n" +
" + CategoryInfo : {3}`n" +
" + FullyQualifiedErrorId : {4}`n"
$fields = $_.InvocationInfo.MyCommand.Name,
$_.ErrorDetails.Message,
$_.InvocationInfo.PositionMessage,
$_.CategoryInfo.ToString(),
$_.FullyQualifiedErrorId
$formatstring -f $fields
エラーメッセージをcatch
ブロックに表示するだけの場合は、現在のオブジェクト変数(その時点でエラーを保持している)をエコーするだけです。
try {
...
} catch {
$_
}
色付きの出力が必要な場合は、上記のフォーマットされた文字列でWrite-Host
を使用します。
try {
...
} catch {
...
Write-Host -Foreground Red -Background Black ($formatstring -f $fields)
}
そうは言っても、通常、例外ハンドラーにエラーメッセージをそのまま表示するのは望ましくありません(そうでなければ、-ErrorAction Stop
は意味がありません)。構造化エラー/例外オブジェクトは、エラー制御を改善するために使用できる追加情報を提供します。たとえば、$_.Exception.HResult
には実際のエラー番号があります。 $_.ScriptStackTrace
および$_.Exception.StackTrace
。したがって、デバッグ時にスタックトレースを表示できます。 $_.Exception.InnerException
は、多くの場合エラーに関する追加情報を含むネストされた例外へのアクセスを提供します(トップレベルのPowerShellエラーは多少一般的です)。次のような方法で、これらのネストされた例外を展開できます。
$e = $_.Exception
$msg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n" + $e.Message
}
$msg
あなたの場合、抽出したい情報は$_.ErrorDetails.Message
にあるようです。オブジェクトまたはJSON文字列があるかどうかは明確ではありませんが、$_.ErrorDetails
のメンバーの型と値に関する情報を取得するには実行する必要があります
$_.ErrorDetails | Get-Member
$_.ErrorDetails | Format-List *
$_.ErrorDetails.Message
がオブジェクトの場合、次のようなメッセージ文字列を取得できるはずです。
$_.ErrorDetails.Message.message
それ以外の場合は、最初にJSON文字列をオブジェクトに変換する必要があります。
$_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -Expand message
処理しているエラーの種類に応じて、特定のタイプの例外には、当面の問題に関するより具体的な情報も含まれる場合があります。たとえば、あなたの場合、エラーメッセージ($_.Exception.Message
)に加えて、サーバーからの実際の応答を含むWebException
があります。
PS C:\> $ e.Exception |取得メンバー TypeName:System.Net.WebException Name MemberType Definition ---- ----------- --------- Equalsメソッドbool Equals(System.Object obj)、bool _Exception.E ... GetBaseExceptionメソッドSystem.Exception GetBaseException()、System.Excep。 .. GetHashCodeメソッドint GetHashCode()、int _Exception.GetHashCode() GetObjectDataメソッドvoid GetObjectData(System.Runtime.Serialization.S ... GetTypeメソッドタイプGetType( )、タイプ_Exception.GetType() ToStringメソッドstring ToString()、string _Exception.ToString() DataプロパティSystem.Collections.IDictionary Data {get;} HelpLinkプロパティstring HelpLink {get; set;} HResultプロパティint HResult {get;} InnerExceptionプロパティSystem.Exception InnerException {get;} Messageプロパティstring Message {get;} 応答プロパティSystem.Net.WebResponse応答{get;} Sourceプロパティ文字列Source {get; set;} StackTraceプロパティ文字列StackTrace {get;} StatusプロパティSystem.Net.WebExceptionStatus Status {get;} TargetSiteプロパティSystem.Reflection.MethodBase TargetSite {get;}
次のような情報が提供されます。
PS C:\> $ e.Exception.Response IsMutuallyAuthenticated:False Cookies:{} Headers:{キープアライブ、接続、コンテンツ長、コンテンツT ...} SupportsHeaders:True ContentLength:198 ContentEncoding: ContentType:text/html; charset = iso-8859-1 CharacterSet:iso-8859-1 Server:Apache/2.4.10 LastModified:17.07.2016 14:39:29 StatusCode:NotFound StatusDescription:Not Found ProtocolVersion:1.1 ResponseUri:http://www.example.com/ Method:POST IsFromCache:False
すべての例外のプロパティセットがまったく同じではないため、特定の例外に対して特定のハンドラーを使用できます。
try {
...
} catch [System.ArgumentException] {
# handle argument exceptions
} catch [System.Net.WebException] {
# handle web exceptions
} catch {
# handle all other exceptions
}
エラーが発生したかどうかに関係なく実行する必要がある操作(ソケットやデータベース接続を閉じるなどのクリーンアップタスク)がある場合は、例外処理後にfinally
ブロックに配置できます。
try {
...
} catch {
...
} finally {
# cleanup operations go here
}
見つけた!
最後のエラーメッセージの$Error[0]
を印刷するだけです。
あなたは付け加えられます:
-ErrorVariable errvar
そして、$errvar
を見てください。
次は私のためにうまくいった
try {
asdf
} catch {
$string_err = $_ | Out-String
}
write-Host $string_err
この結果は、ErrorRecordオブジェクトではなく、文字列として次のようになります
asdf : The term 'asdf' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\TASaif\Desktop\tmp\catch_exceptions.ps1:2 char:5
+ asdf
+ ~~~~
+ CategoryInfo : ObjectNotFound: (asdf:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
本当にモノリシックなErrorRecord構造であることに興味のあるデータがどこに埋まっているのかを見つけようとして、これらの質問に戻ってきます。ほとんどすべての回答は、特定のデータのビットをプルする方法に関する断片的な指示を与えます。
しかし、ConvertTo-Json
を使用してオブジェクト全体をダンプすると、わかりやすいレイアウトでLITERALLY EVERYTHINGを視覚的に確認できるため、非常に役立つことがわかりました。
try {
Invoke-WebRequest...
}
catch {
Write-Host ($_ | ConvertTo-Json)
}
ConvertTo-Json
の-Depth
パラメーターを使用してより深い値を展開しますが、デフォルトの2
:Pを超える場合は細心の注意を払ってください
https://docs.Microsoft.com/en-us/powershell/module/Microsoft.powershell.utility/convertto-json