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

To rzuca następujący wyjątek: „A zasób o tej samej nazwie już istnieje”Catching PEŁEN Exception Message

enter image description here

Jak mogę złapać go w całości albo przynajmniej odfiltrować?

Korzystanie $_.Exception.GetType().FullName daje

System.Net.WebException

i $_.Exception.Message daje

The remote server returned an error: (400) Bad Request.

Odpowiedz

37

Błędy i wyjątki w PowerShell są obiektami strukturyzowane. Komunikat o błędzie wyświetlony na konsoli jest w rzeczywistości sformatowaną wiadomością zawierającą informacje z kilku elementów obiektu błędu/wyjątku. Można (re) konstruowania go samodzielnie tak:

$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 

Jeśli chcesz tylko komunikat o błędzie wyświetlany w bloku catch można po prostu echo aktualną zmienną obiektu (który posiada błąd w tym punkcie):

try { 
    ... 
} catch { 
    $_ 
} 

Jeśli potrzebujesz kolorowego wykorzystanie wyjścia Write-Host z sformatowany ciąg w sposób opisany powyżej:

try { 
    ... 
} catch { 
    ... 
    Write-Host -Foreground Red -Background Black ($formatstring -f $fields) 
} 

z powiedział, że zwykle ty don nie chcesz wyświetlać komunikatu o błędzie, jak to jest w obsłudze wyjątków (w przeciwnym razie -ErrorAction Stop byłoby bezcelowe). Strukturalne obiekty błędów/wyjątków dostarczają dodatkowych informacji, których można użyć w celu lepszej kontroli błędów. Na przykład masz $_.Exception.HResult z rzeczywistym numerem błędu. $_.ScriptStackTrace i $_.Exception.StackTrace, dzięki czemu można wyświetlić ślad stosu podczas debugowania. $_.Exception.InnerException daje dostęp do zagnieżdżonych wyjątków, które często zawierają dodatkowe informacje o błędzie (błędy PowerShell na najwyższym poziomie mogą być nieco ogólne). Można rozwinąć te zagnieżdżone wyjątki z czymś takim:

$e = $_.Exception 
$msg = $e.Message 
while ($e.InnerException) { 
    $e = $e.InnerException 
    $msg += "`n" + $e.Message 
} 
$msg 

W twoim przypadku informacja chcesz wyodrębnić wydaje się być w $_.ErrorDetails.Message.To nie jest dla mnie jasne, jeśli obiekt lub ciąg tam JSON, ale powinieneś być w stanie uzyskać informacje na temat typów i wartości członków $_.ErrorDetails uruchamiając

$_.ErrorDetails | Get-Member 
$_.ErrorDetails | Format-List * 

Jeśli $_.ErrorDetails.Message jest obiektem ty powinny być w stanie uzyskać ciąg wiadomość tak:

$_.ErrorDetails.Message.message 

inaczej trzeba przekonwertować ciąg JSON do obiektu pierwsze:

$_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -Expand message 

W zależności od rodzaju błędu, który obsługuje, wyjątki poszczególnych typów mogą również zawierać bardziej szczegółowe informacje na temat problemu. W twoim przypadku na przykład masz WebException które oprócz komunikatu o błędzie ($_.Exception.Message) zawiera rzeczywistą odpowiedź od serwera:

PS C:\>$e.Exception | Get-Member 

    TypeName: System.Net.WebException 

Name    MemberType Definition 
----    ---------- ---------- 
Equals   Method  bool Equals(System.Object obj), bool _Exception.E... 
GetBaseException Method  System.Exception GetBaseException(), System.Excep... 
GetHashCode  Method  int GetHashCode(), int _Exception.GetHashCode() 
GetObjectData Method  void GetObjectData(System.Runtime.Serialization.S... 
GetType   Method  type GetType(), type _Exception.GetType() 
ToString   Method  string ToString(), string _Exception.ToString() 
Data    Property System.Collections.IDictionary Data {get;} 
HelpLink   Property string HelpLink {get;set;} 
HResult   Property int HResult {get;} 
InnerException Property System.Exception InnerException {get;} 
Message   Property string Message {get;} 
Response Property System.Net.WebResponse Response {get;} 
Source   Property string Source {get;set;} 
StackTrace  Property string StackTrace {get;} 
Status   Property System.Net.WebExceptionStatus Status {get;} 
TargetSite  Property System.Reflection.MethodBase TargetSite {get;}

który dostarcza informacji jak ta:

PS C:\>$e.Exception.Response 

IsMutuallyAuthenticated : False 
Cookies     : {} 
Headers     : {Keep-Alive, Connection, Content-Length, Content-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

Rejestracja nie wszystkie wyjątki mają dokładnie taki sam zestaw właściwości, z których mogą korzystać określone programy obsługi dla określonych wyjątków:

try { 
    ... 
} catch [System.ArgumentException] { 
    # handle argument exceptions 
} catch [System.Net.WebException] { 
    # handle web exceptions 
} catch { 
    # handle all other exceptions 
} 

Jeśli masz operacje, które muszą być wykonane niezależnie od tego, czy wystąpił błąd lub nie (zadania porządkowe, takie jak zamykanie gniazda lub połączenie z bazą danych) można umieścić je w finally bloku po obsługi wyjątków:

try { 
    ... 
} catch { 
    ... 
} finally { 
    # cleanup operations go here 
} 
+0

I już znalazłem odpowiedź, ale jest to o wiele bardziej szczegółowe. Twoje zdrowie. – JustAGuy

+0

Dzięki za dokładne wyjaśnienie. Bardzo przydatne. –

6

Znalazłem ją!

Po prostu wydrukuj $Error[0] dla ostatniego komunikatu o błędzie.

3

można dodać

-ErrorVariable errvar 

A potem spojrzeć w $ errvar