Fehlerbehandlung

Abgeschlossen

Bisher haben Sie gesehen, wie das Hinzufügen von Parametern und Flusssteuerungskonstrukten ihre Skripts flexibel und sicherer machen kann. Manchmal treten jedoch Fehler in Ihren Skripts auf. Sie müssen wissen, wie Sie diese Fehler behandeln können.

Hier sind einige Faktoren zu beachten:

  • Behandeln des Fehlers. Manchmal erhalten Sie Fehler, die behebbar sind, und manchmal ist es besser, das Skript zu beenden. Denken Sie daher darüber nach, welche Art von Fehlern auftreten können und wie sie am besten behandelt werden können.

  • Schweregrad des Fehlers. Es gibt verschiedene Arten von Fehlermeldungen. Einige sind eher Warnungen für den Benutzer, dass etwas nicht in Ordnung ist. Einige sind schwerwiegender und erfordern wirklich die Aufmerksamkeit des Benutzers. Ihr Fehlerbehandlungsansatz hängt vom Typ des Fehlers ab. Der Ansatz kann vom Anzeigen einer Meldung bis hin zum Auslösen der Schweregradfeststellung und möglicherweise zum Beenden des Skripts reichen.

Fehler

Ein Cmdlet oder eine Funktion kann z. B. viele Fehlertypen generieren. Es empfiehlt sich, Code zu schreiben, der jeden möglicherweise auftretenden Fehlertyp abdeckt, und die Fehler entsprechend dem Typ zu behandeln. Angenommen, Sie versuchen, in eine Datei zu schreiben. Je nachdem, was nicht in Ordnung ist, werden Ihnen verschiedene Typen von Fehlern angezeigt. Wenn Sie nicht in die Datei schreiben dürfen, erhalten Sie möglicherweise den einen Fehlertyp. Wenn die Datei nicht vorhanden ist, erhalten Sie einen anderen Fehlertyp usw.

Es gibt zwei Fehlertypen, die beim Ausführen von PowerShell auftreten können:

  • Fehler mit Abbruch. Ein Fehler dieses Typs beendet die Ausführung in der Zeile, in der der Fehler aufgetreten ist. Sie können diese Art von Fehler mithilfe von Try-Catch oder Trap behandeln. Wenn der Fehler nicht behandelt wird, wird das Skript zu diesem Zeitpunkt beendet, und es werden keine Anweisungen ausgeführt.

    Hinweis

    Das Trap-Konstrukt ist jedoch nicht Thema dieses Moduls. Wenn Sie daran interessiert sind, finden Sie weitere Informationen unter About Trap (Informationen zu Trap).

  • Fehler ohne Abbruch. Bei diesem Fehlertyp wird der Benutzer benachrichtigt, dass etwas nicht stimmt, aber das Skript wird fortgesetzt. Sie diese Art von Fehler zu einem Fehler mit Abbruch machen.

Verwalten von Fehlern mithilfe von Try/Catch/Finally

Sie können einen Fehler mit Abbruch als unerwarteten Fehler betrachten. Diese Fehler sind schwerwiegend. Wenn Sie einen Fehler behandeln, sollten Sie überlegen, um welche Art von Fehler es sich handelt und wie Sie damit umgehen müssen.

Es gibt drei verwandte Konstrukte, mit denen Sie diesen Fehlertyp behandeln können:

  • Try. Sie verwenden einen Try-Block, um eine oder mehrere Anweisungen zu kapseln. Sie platzieren den Code, den Sie ausführen möchten – z. B. Code, der in eine Datenquelle schreibt – in geschweiften Klammern. Ein Try-Block muss über mindestens einen Catch- oder Finally-Block verfügen. So sieht es aus:

    Try {
       # Statement. For example, call a command.
       # Another statement. For example, assign a variable.
    }
    
  • Catch. Sie verwenden dieses Schlüsselwort, um einen Fehler abzufangen oder zu behandeln, wenn er auftritt. Anschließend untersuchen Sie das Ausnahmeobjekt, um den aufgetretenen Fehlertyp und die entsprechende Skriptstelle zu ermitteln und zu bestimmen, ob das Skript fortgesetzt werden kann. Ein Catch-Block folgt unmittelbar auf einen Try-Block. Wenn Sie möchten, können Sie mehr als einen Catch einfügen – einen für jeden Fehlertyp. Hier sehen Sie ein Beispiel:

    Try {
       # Do something with a file.
    } Catch [System.IO.IOException] {
       Write-Host "Something went wrong"
    }  Catch {
       # Catch all. It's not an IOException but something else.
    }
    

    Das Skript versucht, einen Befehl auszuführen, der einige E/A-Vorgänge ausführt. Der erste Catch-Block fängt einen bestimmten Fehlertyp ab: [System.IO.IOException]. Der letzte Catch-Block fängt alles ab, was kein [System.IO.IOException]-Element ist.

  • Finally. Die Anweisungen in diesem Block werden unabhängig davon ausgeführt, ob etwas schief geht. Sie werden diesen Block wahrscheinlich nicht sehr häufig verwenden, aber er kann z. B. zum Bereinigen von Ressourcen nützlich sein. Wenn Sie ihn einsetzen möchten, fügen Sie ihn als letzten Block hinzu:

    Try {
       # Do something with a file.
    } Catch [System.IO.IOException] {
       Write-Host "Something went wrong"
    }  Catch {
       # Catch all. It's not an IOException but something else.
    } Finally {
       # Clean up resources.
    }
    

Überprüfen von Fehlern

Ausnahmeobjekte haben wir im Zusammenhang mit dem Abfangen von Fehlern erläutert. Sie können diese Objekte verwenden, um zu überprüfen, was schief gelaufen ist, und entsprechende Maßnahmen zu ergreifen. Ein Ausnahmeobjekt umfasst:

  • Eine Meldung. Die Meldung informiert Sie in wenigen Worten darüber, was schief gelaufen ist.

  • Der StackTrace. Der StackTrace teilt Ihnen mit, welche Anweisungen vor dem Fehler ausgeführt wurden. Stellen Sie sich vor, es gibt einen Aufruf der Funktion A, gefolgt von B, gefolgt von C. Bei C reagiert das Skript nicht mehr. Der StackTrace zeigt diese Kette von Aufrufen an.

  • Die fehlerhafte Zeile. Das Ausnahmeobjekt informiert Sie auch darüber, welche Zeile das Skript ausgeführt hat, als der Fehler aufgetreten ist. Diese Informationen können Sie beim Debuggen des Codes unterstützen.

Wie untersuchen Sie nun ein Ausnahmeobjekt? Es gibt eine integrierte Variable, $_, die über eine exception-Eigenschaft verfügt. Verwenden Sie beispielsweise $_.exception.message, um die Fehlermeldung zu erhalten. Dies könnte im Code folgendermaßen aussehen:

Try {
     # Do something with a file.
   } Catch [System.IO.IOException] {
     Write-Host "Something IO went wrong: $($_.exception.message)"
   }  Catch {
     Write-Host "Something else went wrong: $($_.exception.message)"
   }

Auslösen von Fehlern

In einigen Situationen möchten Sie möglicherweise einen Fehler verursachen:

  • Fehler ohne Abbruch. Bei diesem Fehlertyp benachrichtigt PowerShell Sie lediglich, dass ein Fehler aufgetreten ist, z. B. mithilfe des Write-Error-Cmdlets. Das Skript wird weiter ausgeführt. Dies ist möglicherweise nicht das gewünschte Verhalten. Um den Schweregrad des Fehlers zu erhöhen, können Sie einen Parameter wie -ErrorAction verwenden, um einen Fehler zu verursachen, der wie folgt mit Try/Catch abgefangen werden kann:

    Try {
       Get-Content './file.txt' -ErrorAction Stop
    } Catch {
       Write-Error "File can't be found"
    }
    

    Mithilfe des -ErrorAction-Parameters und des Stop-Werts können Sie einen Fehler verursachen, der von Try/Catch abgefangen werden kann.

  • Geschäftsregeln. Es kann auch Situationen geben, in denen der Code zwar noch nicht aufgehört hat zu reagieren, aber aus geschäftlichen Gründen nicht weiter ausgeführt werden soll. Stellen Sie sich vor, Sie bereinigen die Eingabe und überprüfen, ob ein Parameter ein Pfad ist. Eine geschäftliche Anforderung legt möglicherweise fest, dass nur bestimmte Pfade zulässig sind oder dass der Pfad ein bestimmtes Aussehen haben muss. Wenn die Überprüfungen fehlschlagen, ist es sinnvoll, einen Fehler auszulösen. In solchen Fällen können Sie einen Throw-Block verwenden:

    Try {
       If ($Path -eq './forbidden') 
       {
         Throw "Path not allowed"
       }
       # Carry on.
    
    } Catch {
       Write-Error "$($_.exception.message)" # Path not allowed.
    }
    
    

    Hinweis

    Verwenden Sie Throw im Allgemeinen nicht für die Parametervalidierung. Verwenden Sie stattdessen Validierungsattribute. Wenn Sie Ihren Code nicht mit diesen Attributen verwenden können, ist der Einsatz eines Throw-Elements in Ordnung.