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/catchfără-ErrorAction Stopși să te miri căcatchnu rulează: eroarea e non-terminating. - Să folosești
$_după bloculcatch: acolo nu mai este eroarea. Dacă îți trebuie mai târziu, salveaz-o:$eroare = $_. - Să pui
catchgeneral î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 cuWrite-Warningsau retrimite eroarea cuthrow.
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ă.