⚡ Skripting & Error-Handling

PS 08: Robustes Error-Handling (Try/Catch/Finally)

Verstehe den Unterschied zwischen terminierenden und nicht-terminierenden Fehlern, steuere $ErrorActionPreference und baue ausfallsichere Skripte mit try/catch/finally.

💡 1. Nicht-terminierende vs. Terminierende Fehler

Das Fehlersystem von PowerShell unterscheidet zwei fundamentale Kategorien:

Fehlerart Verhalten Wird von try/catch gefangen?
Nicht-terminierend (z.B. Datei nicht gefunden bei Get-Item) Schreibt in den Error-Stream, Skript läuft einfach weiter. ❌ NEIN! (Wird ignoriert)
Terminierend (z.B. Syntaxfehler, throw, oder -ErrorAction Stop) Stoppt die Pipeline und wirft eine .NET-Exception. ✅ JA! (Wird sofort abgefangen)
⚠️ Die goldene Regel für Try/Catch in PowerShell

Ein try/catch-Block fängt in PowerShell standardmäßig NUR terminierende Fehler ab! Um ein Cmdlet zwingend abfangbar zu machen, musst du -ErrorAction Stop anhängen oder am Skriptanfang $ErrorActionPreference = 'Stop' setzen!

🛡️ 2. Die try / catch / finally Architektur

Fange spezifische .NET-Exceptions gezielt ab und nutze finally, um Datenbankverbindungen, Sperren oder Dateien sicher aufzuräumen:

$ErrorActionPreference = 'Stop'

try {
    # Kritische Operation mit -ErrorAction Stop:
    $content = Get-Content -Path "C:\configs\app.json" -ErrorAction Stop
    $json = $content | ConvertFrom-Json
}
catch [System.IO.FileNotFoundException] {
    Write-Warning "Konfigurationsdatei nicht gefunden: $_"
}
catch [System.Management.Automation.ItemNotFoundException] {
    Write-Warning "PowerShell-Pfad ungültig: $_"
}
catch {
    # Universeller Fallback-Catch:
    Write-Error "Unerwarteter Fehler: $($_.Exception.Message)"
}
finally {
    # Wird IMMER ausgeführt – selbst bei Fehlern oder vorzeitigem return!
    Write-Verbose "Aufräumarbeiten abgeschlossen."
}
🧯 Didaktische Analogie: Das Notfall-Protokoll

try: Der Arbeitsbereich unter Beobachtung.
catch: Die Rettungsmannschaft, die je nach Fehlertyp (Brand, Rohrbruch) den passenden Notfallplan abarbeitet.
finally: Die Hausmeisterin, die garantiert immer das Licht ausschaltet und die Türen verriegelt – ganz egal, was während des Einsatzes passiert ist!

🔍 3. Das Fehler-Objekt ($_ / $Error[0])

Im catch-Block repräsentiert $_ ein vollwertiges ErrorRecord-Objekt mit tiefen Diagnose-Informationen:

catch {
    $err = $_
    $msg  = $err.Exception.Message                 # Fehler-Text
    $type = $err.Exception.GetType().FullName     # Vollständiger .NET-Typ
    $line = $err.InvocationInfo.ScriptLineNumber  # Zeilennummer im Skript
    
    # Eigenen terminierenden Fehler werfen:
    throw "Fehler in Zeile $line: $msg"
}

📑 4. Cheat-Sheet: Error-Handling

Mechanismus Code Bedeutung
$ErrorActionPreference $ErrorActionPreference = 'Stop' Macht alle Skript-Fehler global terminierend.
-ErrorAction Get-Item "file" -ErrorAction Stop Erzwingt terminierenden Fehler für einen Einzelbefehl.
throw throw "Ungültiger Zustand" Löst manuell eine terminierende Exception aus.
finally finally { $handle.Close() } Garantierter Cleanup-Block.

🧠 Diagnostischer Selbst-Check

Überprüfe dein Verständnis zu PowerShell-Architektur, Pipeline-Mechanik und Best Practices mit gezieltem Feedback:

🎯 Aufgaben & Checkliste in aufgabe.ps1

💻 In Web-IDE öffnen → ← Zurück zu PS 07