Az eddigi sok okosságot a hibakezeléssel kapcsolatban mind a cmdletek fejlesztőinek köszönhetjük. Azaz hogy egy cmdlet rendelkezik az –ErrorAction paraméterrel, és ennek különböző értékeire hogyan reagál, az mind leprogramozandó. Ha mi készítünk egy függvényt vagy szkriptet, és abban mi is figyelembe akarjuk venni a globális $ErrorActionPreference változó értékét, vagy mi is implementálni akarjuk az ‑ErrorAction paramétert, akkor ezt a függvényünk, szkriptünk belsejében nekünk le kell programozni.
Ehhez a PowerShell nyelvi szinten a trap kulcsszót biztosítja az 1.0 verziótól kezdve. Ennek szintaxisa így néz ki:
trap [ExceptionType] {code; keyword}
A trap-pel tehát át lehet venni a vezérlést a hibák felmerülésekor. Nézzünk erre pár példát:
trap
{
"Hibajelenség: $_"
}
Remove-Item c:\nemlétezőfile.txt
A fenti példa egy szkript, nézzük mit ad ez kimenetként, ha lefuttatom:
PS C:\> .\_munka\powershell2\scripts\trap1.ps1
Remove-Item
: Cannot find path 'C:\nemlétezőfile.txt' because it does not exis
t.
At
C:\_munka\powershell2\scripts\trap1.ps1:6 char:12
+
Remove-Item <<<<
c:\nemlétezőfile.txt
+ CategoryInfo : ObjectNotFound:
(C:\nemlétezőfile.txt:String) [
Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.Remo
veItemCommand
Nem sok mindent látunk a „gyári” hibajelzéshez képest. Mivelhogy a trap csak megszakító hibákra éled fel, azaz a fenti nem megszakító hibát át kell alakítani megszakító hibává. Nézzük a módosított szkriptet:
trap
{
"Hibajelenség: $_"
}
Remove-Item c:\nemlétezőfile.txt -ErrorAction Stop
Itt már mindenképpen megállíttatom a cmdlet futását bármilyen hibajelenségre. És ennek kimenete:
PS C:\> .\_munka\powershell2\scripts\trap2.ps1
Hibajelenség: Cannot find path 'C:\nemlétezőfile.txt' because it does not exis
t.
Remove-Item
: Cannot find path 'C:\nemlétezőfile.txt' because it does not exis
t.
At
C:\_munka\powershell2\scripts\trap2.ps1:6 char:12
+
Remove-Item <<<<
c:\nemlétezőfile.txt -ErrorAction Stop
+ CategoryInfo : ObjectNotFound:
(C:\nemlétezőfile.txt:String) [
Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId :
PathNotFound,Microsoft.PowerShell.Commands.Remo
veItemCommand
Itt már megjelenik az én trap kódom is. A trap megkapja a hibát jelző objektumot a $_ változóban, amit ki is írtam. Viszont nem rendelkeztem arról, hogy a saját hibakezelő rutinom lefutása után mi történjen, így utána visszakapja a vezérlést a PowerShell, ami szintén kiírja a hibajelzést. Ez felesleges, így módosítsuk a hibakezelést:
trap
{
"Hibajelenség: $_"
continue
}
Remove-Item c:\nemlétezőfile.txt -ErrorAction Stop
Ebben a változatban a trap szkriptblokkjába elhelyeztem egy continue kulcsszót, ami azt jelzi a PowerShellnek, hogy már minden rendben, neki már nem kell foglalkozni a hibával. Nézzük ekkor a kimenetet:
PS C:\> .\_munka\powershell2\scripts\trap3.ps1
Hibajelenség: Cannot find path 'C:\nemlétezőfile.txt' because it does not exis
t.
Fejlesszük tovább a kódot, jó lenne kicsit hasznosabb információkat is kiírni a hibáról:
trap
{
"Hibajelenség: $_"
"-------- Részletek --------------"
$_.Exception.GetType().FullName
$_.InvocationInfo
"-------- Részletek vége ---------"
continue
}
Remove-Item c:\nemlétezőfile.txt -ErrorAction Stop
Nézzük ennek a kimenetét:
PS C:\> .\_munka\powershell2\scripts\trap4.ps1
Hibajelenség: Cannot find path 'C:\nemlétezőfile.txt' because it does not exis
t.
-------- Részletek --------------
System.Management.Automation.ItemNotFoundException
MyCommand : Remove-Item
BoundParameters : {[ErrorAction, Stop], [Path, System.String[]]}
UnboundArguments : {}
ScriptLineNumber : 11
OffsetInLine : 12
HistoryId : 13
ScriptName : C:\_munka\powershell2\scripts\trap4.ps1
Line : Remove-Item c:\nemlétezőfile.txt -ErrorAction Stop
PositionMessage :
At C:\_munka\powershell2\scripts\trap4.ps1:11 char:12
+ Remove-Item <<<< c:\nemlétezőfile.txt -ErrorAction Stop
InvocationName : Remove-Item
PipelineLength : 1
PipelinePosition : 1
ExpectingInput : False
CommandOrigin : Internal
-------- Részletek vége ---------
A „Részletek” első eleme a hibajelenség típusa, azaz az ExceptionType . Jelen esetben ez egy: System.Management.Automation.ActionPreferenceStopException típusú hiba. Ha csak bizonyos típusú hibákra szeretném, hogy a trap-em reagáljon, akkor ezt a típuselnevezést kell a trap paramétereként beírni (lásd nemsokára).
Ezután kiírattam a hibaobjektum InvocationInfo paraméterét, ami természetesen önmaga is egy objektum, így annak is számos tulajdonsága van. Ezen tulajdonságok között láthatjuk, hogy milyen parancs végrehajtása során lépett fel a hiba, milyen szkriptben, mi volt a teljes parancssor, stb. Ezek az információk hasznos segítséget nyújtanak a hiba felderítésében.
Nézzük, mit kapunk, ha egy másik hibajelenséget kap a trap-em, mondjuk egy nullával való osztást:
trap
{
"Hibajelenség: $_"
"-------- Részletek --------------"
$_.Exception.GetType().FullName
$_.InvocationInfo
"-------- Részletek vége ---------"
continue
}
$nulla = 0
8/$nulla
Kicsit trükközni kellett, hiszen korábban láttuk, hogy ha közvetlenül ezt írnám. „8/0”, akkor azt már maga a parancsértelmező kiszúrná, és un. „nontrappable”, azaz nem elkapható hibaként kezelné. Ezért elrejtem egy változóba a nullát, és így osztok vele. Nézzük a kimenetet:
PS C:\> .\_munka\powershell2\scripts\trap5.ps1
Hibajelenség: Attempted to divide by zero.
-------- Részletek --------------
System.DivideByZeroException
MyCommand :
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 12
OffsetInLine : 3
HistoryId : 14
ScriptName : C:\_munka\powershell2\scripts\trap5.ps1
Line : 8/$nulla
PositionMessage :
At C:\_munka\powershell2\scripts\trap5.ps1:12 char:3
+ 8/ <<<< $nulla
InvocationName : /
PipelineLength : 0
PipelinePosition : 0
ExpectingInput : False
CommandOrigin : Internal
-------- Részletek vége ---------
Látjuk a részletek első sorában, hogy ez egy másfajta hiba, egy System.DivideByZeroException típusú. Ezek után, ha én csak az ilyen fajta hibákat akarom lekezelni, akkor a trap definícióját kell módosítani:
trap [System.DivideByZeroException]
{
"Hibajelenség: $_"
"-------- Részletek --------------"
$_.Exception.GetType().FullName
$_.InvocationInfo
"-------- Részletek vége ---------"
continue
}
$nulla = 0
8/$nulla
Remove-Item nemlétezőfile.txt
Ebben a szkriptben a trap mellett látható annak a hibatípusnak a neve, amire szeretnénk, ha a trap-ünk reagálna. Az összes többi hibafajtát a PowerShell fogja lekezelni. A szkript végén kétfajta hibát okozó műveletet hajtok végre. Nézzük, hogyan reagál ezekre a trap:
PS C:\> .\_munka\powershell2\scripts\trap6.ps1
Hibajelenség: Attempted to divide by zero.
-------- Részletek --------------
System.DivideByZeroException
MyCommand :
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 12
OffsetInLine : 3
HistoryId : 15
ScriptName : C:\_munka\powershell2\scripts\trap6.ps1
Line : 8/$nulla
PositionMessage :
At C:\_munka\powershell2\scripts\trap6.ps1:12 char:3
+ 8/ <<<< $nulla
InvocationName : /
PipelineLength : 0
PipelinePosition : 0
ExpectingInput : False
CommandOrigin : Internal
-------- Részletek vége ---------
Remove-Item
: Cannot find path 'C:\nemlétezőfile.txt' because it does not exis
t.
At
C:\_munka\powershell2\scripts\trap6.ps1:14 char:12
+
Remove-Item <<<<
nemlétezőfile.txt
+ CategoryInfo : ObjectNotFound:
(C:\nemlétezőfile.txt:String) [
Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.Remo
veItemCommand
Láthatjuk, hogy csak egyszer fut le az én hibakezelő kódom, a nullával való osztásra. A nem létező fájl törlésekor a PowerShell eredeti hibakezelője futott le.
Az ilyen hibatípusokat legegyszerűbben „megtapasztalás” által lehet felderíteni vagy egy általános trapkezelő rutinnal, vagy az $error tömb elemeinek vizsgálatával. Ha valaki előre fel akar készülni a lehetséges hibákra, akkor a .NET Framework System.Exception leszármaztatott objektumait kell nézni, például a már említett Reflector programmal:
95 . ábra Exception típusok a .NET Frameworkben a Reflector programmal szemlélve
Nagyon sok ilyen hibatípus van, így valószínű a megtapasztalás által könnyebben eredményre jutunk.
Megjegyzés
A System.Exception hibaosztályt lehetőleg ne kezeljük, mert nagyon sok hiba tartozik ebbe.
Az előbb látott trap-eket (csapdákat) a szkriptünk bármelyik szintjén használhatjuk: a globális scope-ban, szkriptek vagy függvények al-scope-jaiban is. Ha egy mélyebb szinten trap által lekezelt hibaesemény lép fel, akkor az – beállítható módon – a magasabb szinteken is jelezhet hibát.
Nézzük azt az esetet, amikor van egy szkriptem, benne egy „fő” trap, egy függvény és abban is egy trap, a végén meg a függvény meghívásával nullával osztok:
trap
{
Write-Error "Külső
trap"
}
function belső
($osztó)
{
trap
{
Write-Error "Belső
trap"
}
20/$osztó
}
belső 0
Nézzük, hogy mi történik, ha futtatom ezt:
PS C:\> .\_munka\powershell2\scripts\nestedtrap.ps1
belső :
Belső trap
At
C:\_munka\powershell2\scripts\nestedtrap.ps1:18 char:6
+ belső
<<<< 0
+ CategoryInfo : NotSpecified: (:) [Write-Error],
WriteErrorExce
ption
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExcepti
on,belső
Attempted to
divide by zero.
At
C:\_munka\powershell2\scripts\nestedtrap.ps1:15 char:5
+ 20/ <<<< $osztó
+ CategoryInfo : NotSpecified: (:) [],
RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Látszik, hogy a belső trap éledt fel, és mivel nem mondtuk, hogy folytathatja, ezért ki is száll a futtatásból a program, megkapjuk még a PowerShell saját hibajelzését is.
Módosítsuk a belső trap-et, mondjuk neki, hogy folytathatja:
trap
{
Write-Error "Külső
trap"
}
function belső
($osztó)
{
trap
{
Write-Error "Belső
trap"
continue
}
20/$osztó
}
belső 0
Nézzük ennek is a kimenetét:
PS C:\> .\_munka\powershell2\scripts\nestedtrap.ps1
belső :
Belső trap
At
C:\_munka\powershell2\scripts\nestedtrap.ps1:18 char:6
+ belső
<<<< 0
+ CategoryInfo : NotSpecified: (:) [Write-Error],
WriteErrorExce
ption
+ FullyQualifiedErrorId :
Microsoft.PowerShell.Commands.WriteErrorExcepti
on,belső
Itt ugye az történt, hogy a belső trap egy folytatással (continue ) zárult le, így a külső környezet már erről a hibáról nem is értesült, azt hiszi, minden rendben.
Zárjuk le akkor a belső trap-et egy break -kel:
trap
{
Write-Error "Külső
trap"
}
function belső
($osztó)
{
trap
{
Write-Error "Belső
trap"
break
}
20/$osztó
}
belső 0
Ennek kimenete:
PS C:\> .\_munka\powershell2\scripts\nestedtrap.ps1
belső :
Belső trap
At
C:\_munka\powershell2\scripts\nestedtrap.ps1:17 char:6
+ belső
<<<< 0
+ CategoryInfo : NotSpecified: (:) [Write-Error],
WriteErrorExce
ption
+ FullyQualifiedErrorId :
Microsoft.PowerShell.Commands.WriteErrorExcepti
on,belső
C:\_munka\powershell2\scripts\nestedtrap.ps1
: Külső trap
At line:1
char:44
+ .\_munka\powershell2\scripts\nestedtrap.ps1
<<<<
+ CategoryInfo : NotSpecified: (:) [Write-Error],
WriteErrorExce
ption
+ FullyQualifiedErrorId :
Microsoft.PowerShell.Commands.WriteErrorExcepti
on,nestedtrap.ps1
Attempted to
divide by zero.
At
C:\_munka\powershell2\scripts\nestedtrap.ps1:14 char:5
+ 20/ <<<< $osztó
+ CategoryInfo : NotSpecified: (:) [],
RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Itt már mindkét szint trapje megjelenik, hiszen a belső trap rendhagyó módon, egy megtöréssel (break) ért véget, ami kívülről nézve is hibát jelez. Ezért a külső trap is felélesedik és az is jelzi a hibát.
Mindezek figyelembevételével el lehet dönteni, hogy hol érdemes, és a működés szempontjából hol kell trapet elhelyezni.
Gyakori hibakezelési feladat, hogy a függvényünk, szkriptünk használata során nem ad meg valaki valamilyen kötelező paramétert. Ennek kezelésére már láttuk a throw kulcsszót a 1.6.2.3 Hibajelzés fejezetben, de ennek hatására megjelenő hibajelzés nem annyira szép, mert nem csak az általunk megadott szöveg kerül kiírásra, hanem egyéb szövegek is. Adódik az ötlet, hogy akkor kapjuk el egy trap-pel az általunk throw-val dobott hibajelzést, és szabjuk testre a trap kódjában a hibajelzést.
Készítettem egy újabb szkriptet az előzőek alapján:
trap
{
"Hibajelenség: $_"
"-------- Részletek --------------"
$_.Exception.GetType().FullName
$_.InvocationInfo
"-------- Részletek vége ---------"
continue
}
function dupla ($v = $(throw "Adj meg paramétert!"))
{
$v*2
}
dupla
A trap része nem nagyon változott, és ott van mellette a korábban már látott duplázó függvényem, hibajelzéssel a paraméterhiány esetére. A szkript legvégén meghívom magát a dupla függvényt mindenféle paraméter nélkül. Mindennek ez lesz az eredménye:
PS C:\> .\_munka\powershell2\scripts\trap7.ps1
Hibajelenség: Adj meg paramétert!
-------- Részletek --------------
System.Management.Automation.RuntimeException
MyCommand :
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 11
OffsetInLine : 29
HistoryId : 24
ScriptName : C:\_munka\powershell2\scripts\trap7.ps1
Line : function dupla ($v = $(throw "Adj meg paramétert!"))
PositionMessage :
At C:\_munka\powershell2\scripts\trap7.ps1:11 char:29
+ function dupla ($v = $(throw <<<< "Adj meg paramétert!")
)
InvocationName : throw
PipelineLength : 0
PipelinePosition : 0
ExpectingInput : False
CommandOrigin : Internal
-------- Részletek vége ---------
Tényleg működik a throw elkapása, csak az én általam megadott hibajelzés jelent meg, viszont elég általánosnak tűnik a hiba típusa:
System.Management.Automation.RuntimeException.
Ez nem túl specifikus, hanem általános futási hiba. Viszont lehetünk specifikusabbak, adjunk a throw-val egy értelmesebb hibaobjektumot a trap számára, azaz ne csak egy egyszerű szöveget adjunk neki, hanem egy megfelelő Exception objektumot!
trap
{
"Hibajelenség: $_"
"-------- Részletek --------------"
$_.Exception.GetType().FullName
$_.InvocationInfo
"-------- Részletek vége ---------"
continue
}
function dupla ($v = $(throw `
(New-Object System.ArgumentException `
-arg
"Adjál meg valamit, amit duplázni
lehet!")))
{
$v*2
}
dupla
En úgy gondoltam, hogy az ilyen jellegű hiba leírására a System.ArgumentException típus lesz a legjobb, így ennek egy objektumát hozom létre a throw paramétereként. Ráadásul ennek az objektumnak a konstruktora argumentumot is képes fogadni, az általam megadott hibaleírást szöveggel. Így már nagyon elegáns és hibaspecifikus lesz a kimenete is:
PS C:\> .\_munka\powershell2\scripts\trap8.ps1
Hibajelenség: Adjál meg valamit, amit duplázni lehet!
-------- Részletek --------------
System.ArgumentException
MyCommand :
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 11
OffsetInLine : 29
HistoryId : 25
ScriptName : C:\_munka\powershell2\scripts\trap8.ps1
Line : function dupla ($v = $(throw `
PositionMessage :
At C:\_munka\powershell2\scripts\trap8.ps1:11 char:29
+ function dupla ($v = $(throw <<<< `
InvocationName : throw
PipelineLength : 0
PipelinePosition : 0
ExpectingInput : False
CommandOrigin : Internal
-------- Részletek vége ---------
Így már specifikusabb trap-et is lehet készíteni, ami csak erre a hibatípusra éled fel.
A PowerShell 2.0-ban új hibakezelési lehetőség is megjelent, amit a Try , Catch és Finally kulcsszavakkal tudunk munkára bírni. A Try szekcióba tegyük azt a szkriptrészt, ahol előfordulhat az a hiba, amit kezelni akarunk. Fontos, hogy csak megszakító hibákat kezel le ez a lehetőség is, márpedig alaphelyzetben a PowerShell cmdletek nem megszakító hibát eredményeznek. Ezt mindjárt egy példán is megnézzük. Legyen egy olyan egyszerű függvényünk, ami töröl egy paraméterként megadott elérési úton található fájlt:
function deletefile
($path)
{
try {remove-item
-Path $path}
catch {"Nincs ilyen fájl!"}
finally {"Itt a vég!"}
}
Nézzük, mit ad ez eredményül:
[93] PS C:\> deletefile c:\nincs.txt
Remove-Item
: Cannot find path 'C:\nincs.txt' because it does not exist.
At line:3
char:21
+ try {remove-item <<<< -Path $path}
+ CategoryInfo : ObjectNotFound: (C:\nincs.txt:String)
[Remove-I
tem], ItemNotFoundException
+ FullyQualifiedErrorId :
PathNotFound,Microsoft.PowerShell.Commands.Remo
veItemCommand
Itt a vég!
Ez a standard PowerShelles hibajelzés, és nem az, amit vártunk. Ennek oka az, hogy amint említettem, a PowerShell cmdletek hibái legtöbbször nem megszakító jellegűek, és a Try-Catch csak megszakító hibára működik. Hogyan lehet ezt megszakítóvá alakítani? Állítsuk át az $ErrorActionPreference változót Stop értékűre, vagy még inkább az adott cmdletnél az ‑ErrorAction paramétert:
function deletefile
($path)
{
try {remove-item
-Path $path -ErrorAction Stop}
catch {"Nincs ilyen fájl!"}
finally {"Itt a vég!"}
}
Nézzük, most hogyan fut:
[95] PS C:\> deletefile c:\nincs.txt
Nincs ilyen fájl!
Itt a vég!
Na, ez az, amire számítottunk. Látható, hogy a „Finally” rész mindig lefut, még akkor is, ha nincs hiba:
[97] PS C:\> deletefile c:\a.txt
Itt a vég!
Olyannyira lefut a finally, hogy ha a catch részben return van, a finally blokk még akkor is lefut:
function deletefile ($path){
try {remove-item -Path $path -ErrorAction Stop}
catch {
"Nincs ilyen fájl!"
return -1
}
finally {"Itt a vég!"}
"Ez a normális vég"
}
Ha ezt futtatjuk:
PS C:\> deletefile -path c:\nemlétező.txt
Nincs ilyen fájl!
-1
Itt a vég!
A kimenet nagyon érdekes! Elsőként megkapjuk a „Nincs ilyen fájl!”-t a catch blokkból. Majd megkapjuk az ottani return -1-ét, idáig minden rendben. De most jön a meglepetés! Még ezek után megkapjuk a finally „Itt a vég!”-jét is!
Ha nem történik hiba, a finally akkor is lefut:
PS C:\> deletefile -path C:\PowerShell\törölni.txt
Itt a vég!
Ez a normális vég
Ilyenkor a sorrend a normális, előbb a finally fut le, majd kapjuk a függvény végleges kimenetét.
Megjegyzés
Látható tehát, hogy a return nem feltétlenül a függvényünk vagy szkriptünk utolsó művelete. Ezután, ha van finally blokkunk és hiba történt, akkor a finally hajtódik végre utoljára.
Természetesen a Catch részt is tehetjük csak bizonyos hibákra is érzékennyé:
function dl ($url, $cél)
{
try
{
$wc = new-object System.Net.WebClient
$wc.DownloadString($url) > $cél
}
catch [System.Management.Automation.MethodException],
[System.Management.Automation.DriveNotFoundException]
{
$error[0].Exception.GetType().FullName
"Nem tudok letölteni $url helyről $cél
helyre."
}
catch
{
$error[0].Exception.GetType().FullName
"Valami
egyéb hiba van."
}
}
Ebben az egyszerű példában a dl függvény az $url helyről letölti a weboldalt a $cél helyre. Nézzük, hogyan reagál ez a különböző hibákra:
PS C:\> dl http://www.iqjb.hu c:\nincs\yyy.txt
System.IO.DirectoryNotFoundException
Valami egyéb hiba van.
A fenti esetben a célkönyvtár nem létezik. Ennek hibatípusa:
System.IO.DirectoryNotFoundException,
amit az első Catch részben nem szűrtem, így az „bezuhant” a második Catch-be, azaz az ottani hibaszöveget írta ki.
PS C:\> dl http://www.iqjb.hu x:\yyy.txt
System.Management.Automation.DriveNotFoundException
Nem tudok letölteni http://www.iqjb.hu helyről x:\yyy.txt helyre.
Ebben az esetben a cél meghajtó nem létezik, ez az első Catch blokkban van lekezelve, ahogy a következő eset is:
PS C:\> dl http://www.iqjb.xx c:\_mobil\yyy.txt
System.Management.Automation.MethodInvocationException
Nem tudok letölteni http://www.iqjb.xx helyről c:\_mobil\yyy.txt helyre.
Látható tehát, hogy átláthatóan, követhetőbben lehet lekezelni a különböző hibajelenségeket.
Megjegyzés
Sajnos a cmdletek Stop módon való megállítása egy kicsit megkavarja a Try-Catch működését. Nézzünk erre egy példát:
function deletefile
($path)
{
try {remove-item
-Path $path -ErrorAction Stop}
catch {$error[0].Exception.GetType().FullName;
"Nincs ilyen!"}
}
Ha ezt futtatom egy nem létező fájlra, akkor a már korábbal látotthoz hasonló kimenetet kapunk:
PS C:\> Deletefile c:\yyyy.txt
System.Management.Automation.ItemNotFoundException
Nincs ilyen!
Látható, hogy milyen a hiba típusa. Ha erre akarok szűrni, akkor nézzük, hogy mi történik:
function deletefile
($path)
{
try {remove-item
-Path $path -ErrorAction Stop}
catch [System.Management.Automation.ItemNotFoundException]
{$error[0].Exception.GetType().FullName;
"Nincs ilyen!"}
}
Ennek ugyanazt kellene adnia kimenetként, de nem:
PS C:\> Deletefile c:\yyyy.txt
Cannot find
path 'C:\yyyy.txt' because it does not exist.
At :line:4
char:21
+ try {remove-item <<<< -Path $path -ErrorAction
Stop}
Na, ezt nem értem teljesen, illetve valami olyasmi történik, mintha egy burkolt Throw történne valahol a Catch belsejében… Ennek kezelésére a következő fejezetben teszek javaslatot.
Végezetül pár szempont, hogy mikor érdemes trap-et, és mikor Try-Catch-et alkalmazni:
Trap: saját scope-ja van, viszont globális a hatása, azaz bárhol is van a hiba, azt a trap elkapja. Nem lehet a hibát „tovább dobni”, azaz egy üres Throw kifejezés egy speciális, új hibát generál, aminek a típusa „ScriptHalted”.
Try/Catch: nincs külön scope-ja, szelektíven, csak a Try „testében” levő hibákra reagál. A hiba tovább dobható egy üres Throw kifejezéssel.