Attraper PLEIN de Message d'Exception

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

ceci jette l'exception suivante:

enter image description here

Comment puis-je l'attraper entièrement ou au moins filtrer la "une ressource avec le même nom existe déjà."?

en utilisant $_.Exception.GetType().FullName les rendements

Système.Net.WebException

et $_.Exception.Message donne

le serveur distant a renvoyé une erreur: (400) mauvaise requête.

33
demandé sur Ansgar Wiechers 2016-07-17 11:31:26

4 réponses

les erreurs et les exceptions dans PowerShell sont des objets structurés. Le message d'erreur que vous voyez imprimé sur la console est en fait un message formaté contenant des informations provenant de plusieurs éléments de l'objet erreur/exception. Vous pouvez (re-)construire vous-même comme ceci:

$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

si vous voulez juste que le message d'erreur s'affiche dans votre catch bloc, vous pouvez simplement l'écho de l'objet courant variable qui contient l'erreur à l'instant):

try {
  ...
} catch {
  $_
}

si vous avez besoin la sortie colorée utiliser Write-Host avec une chaîne formatée, comme décrit ci-dessus:

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

cela dit, habituellement vous ne voulez pas simplement afficher le message d'erreur comme-est dans un gestionnaire d'exception (sinon le -ErrorAction Stop serait inutile). Les objets erreur structurée/exception vous fournissent des informations supplémentaires que vous pouvez utiliser pour un meilleur contrôle des erreurs. Par exemple, vous avez $_.Exception.HResult avec le numéro d'erreur. $_.ScriptStackTrace et $_.Exception.StackTrace, de sorte que vous pouvez afficher stacktraces quand débogage. $_.Exception.InnerException vous donne accès à des exceptions imbriquées qui contiennent souvent des informations supplémentaires sur l'erreur (les erreurs de PowerShell de haut niveau peuvent être quelque peu génériques). Vous pouvez dérouler ces exceptions imbriquées avec quelque chose comme ceci:

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

dans votre cas, l'information que vous voulez extraire semble être en $_.ErrorDetails.Message. Il n'est pas tout à fait clair pour moi si vous avez un objet ou une chaîne JSON là, mais vous devriez être en mesure d'obtenir des informations sur les types et les valeurs des membres $_.ErrorDetails en cours d'exécution

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

Si $_.ErrorDetails.Message est un objet, vous devriez être en mesure d'obtenir la chaîne de message comme ceci:

$_.ErrorDetails.Message.message

sinon vous devez convertir la chaîne JSON en objet en premier:

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

selon le type d'erreur que vous manipulez, les exceptions de types particuliers peuvent aussi inclure des informations plus spécifiques sur le problème en question. Dans votre cas, par exemple, vous avez un WebException qui, en plus du message d'erreur ($_.Exception.Message) contient la réponse actuelle du serveur:

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;}

qui vous offre avec des informations comme ceci:

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

puisque toutes les exceptions n'ont pas exactement le même ensemble de propriétés, Vous pouvez utiliser des gestionnaires spécifiques pour les exceptions particulières:

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

si vous avez des opérations qui doivent être effectuées indépendamment du fait qu'une erreur se soit produite ou non (tâches de nettoyage comme la fermeture d'une connexion socket ou d'une base de données), vous pouvez les mettre dans un finally bloc après le traitement d'exception:

try {
  ...
} catch {
  ...
} finally {
  # cleanup operations go here
}
56
répondu Ansgar Wiechers 2018-02-23 12:12:47

je l'ai trouvé!

il suffit d'imprimer $Error[0] pour le dernier message d'erreur.

9
répondu JustAGuy 2016-07-17 08:55:25

vous pouvez ajouter

-ErrorVariable errvar

Et puis regardez dans $errvar

5
répondu Tim Ker 2016-07-17 10:25:26

La suite a bien fonctionné pour moi

try {
    asdf
} catch {
    $string_err = $_ | Out-String
}

write-host $string_err

Le résultat est le suivant comme une chaîne de caractères au lieu d'un ErrorRecord objet

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
0
répondu Tareq Saif 2018-07-23 23:26:00