web-dev-qa-db-ja.com

FULL例外メッセージをキャッチ

考慮してください:

Invoke-WebRequest $sumoApiURL -Headers @{"Content-Type"= "application/json"} -Credential $cred -WebSession $webRequestSession -Method post -Body $sumojson -ErrorAction Stop

これにより、次の例外がスローされます。

Enter image description here

どうすればそれを完全にキャッチできますか、少なくとも「同じ名前のリソースがすでに存在している」を除外できますか?

$_.Exception.GetType().FullNameを使用すると、

System.Net.WebException

そして$_.Exception.Message

リモートサーバーがエラーを返しました:(400)Bad Request。

46
JustAGuy

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
}
76
Ansgar Wiechers

見つけた!

最後のエラーメッセージの$Error[0]を印刷するだけです。

10
JustAGuy

あなたは付け加えられます:

-ErrorVariable errvar

そして、$errvarを見てください。

5
Tim Ker

次は私のためにうまくいった

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
3
Tareq Saif

本当にモノリシックな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

1
mmseng