Hibakezelés saját függvényeinkben (trap, try, catch, finally)

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.

Többszintű csapda

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.

Dobom és elkapom

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.

Try, Catch, Finally

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.



Word To HTML Converter