try / catch / finally în PowerShell

Control și funcții Windows PowerShell 2.0

try/catch prinde erorile care opresc o comandă, iar finally rulează mereu; pentru erorile obișnuite ale cmdlet-urilor pui -ErrorAction Stop.

Sintaxă
try { ... }
catch [TipExceptie] { ... }
catch { $_.Exception.Message }
finally { ... }

Ce face try / catch / finally

Codul care poate eșua se pune în try { }. Dacă apare o eroare care oprește execuția (terminating error), PowerShell sare în primul bloc catch potrivit; în el, eroarea curentă este în $_ (un ErrorRecord), iar mesajul în $_.Exception.Message. Un catch [System.IO.IOException] prinde doar acel tip de excepție (și tipurile derivate), iar un catch fără tip prinde restul. Blocul finally rulează oricum, cu sau fără eroare, chiar și la Ctrl+C, și e locul pentru curățenie.

Atenție: majoritatea erorilor cmdlet-urilor (fișier lipsă, acces refuzat la un element) sunt non-terminating: se afișează, iar scriptul continuă, deci catch nu le vede. Ca să le prinzi, adaugă parametrul comun -ErrorAction Stop comenzii respective sau setează $ErrorActionPreference = 'Stop' la începutul scriptului.

Cu throw "mesaj" generezi tu o eroare care oprește execuția, de exemplu când un parametru are o valoare nepermisă. Într-un catch, throw fără argumente retrimite eroarea mai departe după ce ai scris-o într-un log. Blocurile try/catch/finally există din Windows PowerShell 2.0; în 1.0 exista doar trap.

Parametri

Parametru Descriere
try { } Codul supravegheat.
catch [Tip] { } Prinde erorile de tipul dat; pot fi mai multe blocuri, de la specific la general.
catch { } Prinde orice eroare care oprește execuția.
finally { } Rulează întotdeauna, la final.
$_ / $_.Exception.Message Eroarea curentă în catch și mesajul ei.
-ErrorAction Stop Transformă erorile non-terminating ale unui cmdlet în erori care pot fi prinse.
throw Generează o eroare; fără argument, în catch, retrimite eroarea curentă.

Exemple

Exemplul 1: Fișier lipsă, prins cu -ErrorAction Stop

Fără -ErrorAction Stop, eroarea s-ar afișa, dar nu ar ajunge în catch. finally rulează în ambele cazuri.

try {
    Get-Content C:\Proiecte\facturi\lipsa.txt -ErrorAction Stop
}
catch {
    "Eroare: $($_.Exception.Message)"
}
finally {
    'Verificare terminată'
}

Ieșire în terminal

Eroare: Cannot find path 'C:\Proiecte\facturi\lipsa.txt' because it does not exist.
Verificare terminată

Exemplul 2: Un catch pentru un tip anume de eroare

Primul catch tratează doar elementele care nu există; orice altă eroare ajunge în al doilea.

try {
    Get-Item C:\Proiecte\arhiva-2025 -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
    'Arhiva nu există încă.'
}
catch {
    "Altă problemă: $($_.Exception.Message)"
}

Ieșire în terminal

Arhiva nu există încă.

Exemplul 3: Generezi propria eroare cu throw

Funcția refuză o sumă negativă; apelantul prinde eroarea și afișează mesajul.

function Get-Pret {
    param([decimal]$Suma)
    if ($Suma -lt 0) { throw "Suma nu poate fi negativă: $Suma" }
    "Preț: $Suma lei"
}
try {
    Get-Pret -Suma 25
    Get-Pret -Suma -5
}
catch {
    "Prins: $($_.Exception.Message)"
}

Ieșire în terminal

Preț: 25 lei
Prins: Suma nu poate fi negativă: -5

Greșeli frecvente

  • Să înconjori un cmdlet cu try/catch fără -ErrorAction Stop și să te miri că catch nu rulează: eroarea e non-terminating.
  • Să folosești $_ după blocul catch: acolo nu mai este eroarea. Dacă îți trebuie mai târziu, salveaz-o: $eroare = $_.
  • Să pui catch general înaintea unuia specific: primul care se potrivește câștigă, deci cel specific nu mai ajunge să ruleze.
  • Să „înghiți” erorile cu un catch { } gol: scriptul pare reușit, dar nu știi ce a eșuat. Scrie măcar mesajul cu Write-Warning sau retrimite eroarea cu throw.

Comenzi înrudite

  • if / elseif / else: if rulează un bloc de cod doar când condiția e adevărată; elseif și else tratează celelalte cazuri, iar ?: (din PowerShell 7.0) e forma scurtă.
  • Funcții și param(): O funcție grupează cod sub un nume; param() îi declară parametrii, cu tip și valoare implicită, iar [CmdletBinding()] o face să meargă ca un cmdlet.
  • Write-Host / Write-Output: Write-Host scrie text doar pe ecran (cu culori), Write-Output trimite valori în pipeline, unde pot fi salvate într-o variabilă sau prelucrate.
  • Test-Path: Verifică dacă o cale există și întoarce True sau False; poate cere să fie fișier sau folder și să fie mai nouă decât o dată.