PowerShell try / catch / finally

j'ai récemment écrit un script Powershell qui fonctionne très bien-cependant, j'aimerais maintenant mettre à jour le script et ajouter quelques vérifications / manipulations d'erreurs - mais j'ai été déconcerté au premier obstacle qu'il semble. Pourquoi ne pas le code suivant fonctionne?

try {
  Remove-Item "C:somenonexistentfolderfile.txt" -ErrorAction Stop
}

catch [System.Management.Automation.ItemNotFoundException] {
  "item not found"
}

catch {
  "any other undefined errors"
  $error[0]
}

finally {
  "Finished"
}

L'erreur est pris dans le deuxième bloc catch - Vous pouvez voir la sortie de $error[0]. Évidemment, je voudrais l'attraper dans le premier bloc - Qu'est-ce que je manque? Merci

41
demandé sur Adi Inbar 2011-07-21 20:07:55

2 réponses

-ErrorAction Stop changer les choses pour vous. Essayez d'ajouter ceci et voyez ce que vous obtenez:

Catch [System.Management.Automation.ActionPreferenceStopException] {
"caught a StopExecution Exception" 
$error[0]
}
35
répondu Bruce 2017-02-23 22:02:34

C'est très bizarre.

je suis passé par ItemNotFoundException's les classes de base et testé de nombreuses catches pour voir ce capture:

try {
  remove-item C:\nonexistent\file.txt -erroraction stop
}
catch [System.Management.Automation.ItemNotFoundException] {
  write-host 'ItemNotFound'
}
catch [System.Management.Automation.SessionStateException] {
  write-host 'SessionState'
}
catch [System.Management.Automation.RuntimeException] {
  write-host 'RuntimeException'
}
catch [System.SystemException] {
  write-host 'SystemException'
}
catch [System.Exception] {
  write-host 'Exception'
}
catch {
  write-host 'well, darn'
}

Comme il s'avère, la sortie a été 'RuntimeException'. J'ai aussi essayé avec une autre exception CommandNotFoundException:

try {
  do-nonexistent-command
}
catch [System.Management.Automation.CommandNotFoundException] {
  write-host 'CommandNotFoundException'
}
catch {
  write-host 'well, darn'
}

sortie 'CommandNotFoundException' correctement.

je me souviens vaguement avoir lu ailleurs (même si je n'ai pas pu le retrouver) des problèmes avec ça. Dans de tels cas où le filtrage d'exception ne fonctionnait pas correctement, ils attraperaient le plus proche Type ils pourraient ensuite utiliser un switch. Le code suivant juste les captures Exception au lieu de RuntimeException, mais switch l'équivalent de mon premier exemple qui vérifie tous les types de base de ItemNotFoundException:

try {
  Remove-Item C:\nonexistent\file.txt -ErrorAction Stop
}
catch [System.Exception] {
  switch($_.Exception.GetType().FullName) {
    'System.Management.Automation.ItemNotFoundException' {
      write-host 'ItemNotFound'
    }
    'System.Management.Automation.SessionStateException' {
      write-host 'SessionState'
    }
    'System.Management.Automation.RuntimeException' {
      write-host 'RuntimeException'
    }
    'System.SystemException' {
      write-host 'SystemException'
    }
    'System.Exception' {
      write-host 'Exception'
    }
    default {'well, darn'}
  }
}

écrit 'ItemNotFound', comme il se doit.

23
répondu Joel B Fant 2011-07-21 17:25:51