about_Try_Catch_Finally

Krátký popis

Popisuje, jak používat try, catcha finally bloky pro zpracování chyb ukončování příkazů a ukončování skriptů.

Dlouhý popis

Pomocí bloků try, catcha finally můžete reagovat na ukončovací chyby ve skriptech nebo je zpracovat. PowerShell obsahuje dva druhy ukončovaných chyb:

  • ukončující chyby, které zastavují aktuální příkaz a
  • Chyby ukončující skripty , které odvíjely celý zásobník volání

Oba druhy jsou zachyceny try/catch. Příkaz můžete použít trap také ke zpracování ukončování chyb. Další informace naleznete v tématu about_Trap. Úplný přehled všech typů chyb najdete v tématu about_Error_Handling.

Chyba ukončující příkaz zastaví spuštění aktuálního příkazu, ale PowerShell pokračuje v dalším příkazu, pokud se chyba také ukončuje skriptem. Chyba ukončující skript (například chyba vytvořená klíčovým slovem throw ) zastaví celý skript, pokud ho nezachytí try/catch blok nebo trap příkaz.

Poznámka

$ErrorActionPreference může potlačit throw. Pokud je nastavená SilentlyContinue hodnota nebo Ignore, chyba se nešíruje a provádění pokračuje v dalším příkazu. Podrobnosti najdete v části Chyby ukončování skriptuabout_Error_Handling.

Pomocí bloku try definujte oddíl skriptu, ve kterém chcete, aby PowerShell monitoroval chyby. Pokud dojde k chybě v try bloku, chyba se nejprve uloží do $Error automatické proměnné. PowerShell pak vyhledá blok catch pro zpracování chyby. Pokud příkaz try nemá odpovídající blok catch, PowerShell bude dál hledat odpovídající příkaz catch bloku nebo trap v nadřazených oborech. Po dokončení catch bloku nebo pokud se nenajde žádný vhodný blok catch nebo příkaz trap, spustí se blok finally. Pokud chybu nelze zpracovat, chyba se zapíše do datového proudu chyb.

Blok catch může obsahovat příkazy pro sledování chyby nebo obnovení očekávaného toku skriptu. Blok catch může určit, které typy chyb zachytí. Příkaz try může obsahovat více bloků catch pro různé druhy chyb.

Blok finally můžete použít k uvolnění všech prostředků, které už váš skript nepotřebuje.

try, catcha finally se podobají try, catcha finally klíčová slova použitá v programovacím jazyce C#.

Syntaxe

Příkaz try obsahuje blok try, nula nebo více bloků catch a nula nebo jeden blok finally. Příkaz try musí mít alespoň jeden blok catch nebo jeden blok finally.

Následující příklad ukazuje syntaxi bloku try:

try {<statement list>}

Za klíčovým slovem try následuje seznam příkazů ve složených závorkách. Pokud při spuštění příkazů v seznamu příkazů dojde k ukončovací chybě, skript předá objekt chyby z try bloku příslušnému catch bloku.

Následující příklad ukazuje syntaxi bloku catch:

catch [[<error type>][',' <error type>]*] {<statement list>}

Typy chyb se zobrazují v hranatých závorkách. Vnější závorky označují, že prvek je volitelný.

Za klíčovým slovem catch následuje volitelný seznam specifikací typu chyby a seznam příkazů. Pokud dojde k ukončovací chybě v bloku try, PowerShell vyhledá příslušný blok catch. Pokud je nalezena, příkazy v bloku catch se spustí.

Blok catch může zadat jeden nebo více typů chyb. Typ chyby je výjimka rozhraní Microsoft .NET Framework nebo výjimka odvozená z výjimky rozhraní .NET Framework. Blok catch zpracovává chyby zadané třídy výjimek rozhraní .NET Framework nebo jakékoli třídy odvozené ze zadané třídy.

Pokud blok catch určuje typ chyby, catch blokování tento typ chyby zpracuje. Pokud blok catch nezadá typ chyby, catch blokování zpracuje všechny chyby, ke kterým došlo v bloku try. Příkaz try může obsahovat více bloků catch pro různé zadané typy chyb.

Následující příklad ukazuje syntaxi bloku finally:

finally {<statement list>}

Za klíčovým slovem finally následuje seznam příkazů, který se spustí při každém spuštění skriptu, a to i v případě, že příkaz try běžel bez chyby nebo došlo k chybě v příkazu catch.

Všimněte si, že stisknutím klávesy CTRL+C kanál zastavíte. Objekty odeslané do kanálu se nezobrazí jako výstup. Proto pokud zahrnete příkaz, který se má zobrazit, například "Finally block has run", nezobrazí se po stisknutí CTRL+C, i když finally blok běžel.

Zachytávání chyb

Následující ukázkový skript ukazuje blok try s blokem catch:

try { NonsenseString }
catch { "An error occurred." }

Klíčové slovo catch musí okamžitě následovat za blokem try nebo jiným blokem catch.

PowerShell nerozpozná "NesmyslyString" jako rutinu nebo jinou položku. Spuštění tohoto skriptu vrátí následující výsledek:

An error occurred.

Když skript narazí na "NesmyslyString", způsobí ukončující chybu. Blok catch zpracovává chybu spuštěním seznamu příkazů uvnitř bloku.

POUŽITÍ VÍCE PŘÍKAZŮ CATCH

Příkaz try může mít libovolný počet bloků catch. Následující skript má například blok try, který stáhne MyDoc.doca obsahuje dva catch bloky:

try {
    $wc = New-Object System.Net.WebClient
    $wc.DownloadFile("https://httpbin.org/MyDoc.doc","C:\temp\MyDoc.doc")
} catch [System.Net.WebException],[System.IO.IOException] {
    "Unable to download MyDoc.doc from https://httpbin.org."
} catch {
    "An error occurred that could not be resolved."
}

První blok catch zpracovává chyby typů system.Net.WebException System.NET.WebException a System.IO.IOException. Druhý blok catch nezadá typ chyby. Druhý catch blok zpracovává všechny ostatní ukončující chyby, ke kterým dochází.

PowerShell odpovídá typům chyb podle dědičnosti. Blok catch zpracovává chyby zadané třídy výjimek rozhraní .NET Framework nebo jakékoli třídy odvozené ze zadané třídy. Následující příklad obsahuje blok catch, který zachytí chybu "Command Not Found":

catch [System.Management.Automation.CommandNotFoundException] {
    "Inherited Exception"
}

Zadaný typ chyby, CommandNotFoundException, dědí z System.SystemException typ. Následující příklad také zachytí chybu Příkaz Nenalezena:

catch [System.SystemException] {"Base Exception" }

Tento blok catch zpracovává chybu Příkaz nenalezena a další chyby, které dědí z typu SystemException.

Pokud zadáte třídu chyby a jednu z jejích odvozených tříd, umístěte catch blok odvozené třídy před catch bloku pro obecnou třídu.

Poznámka

PowerShell zabalí všechny výjimky v RuntimeException typu. Proto se zadáním typu chyby System.Management.Automation.RuntimeException chová stejně jako nekvalifikovaný blok catch.

Použití soutisků při pokusu o zachycení

Pokud dojde k ukončovací chybě v bloku try s trap definovaným v rámci try bloku, i když existuje odpovídající blok catch, příkaz trap převezme kontrolu.

Pokud trap existuje ve vyšším bloku než trya v aktuálním oboru neexistuje odpovídající blok catch, trap převezme kontrolu, i když má některý nadřazený obor odpovídající blok catch.

Přístup k informacím o výjimce

catch V rámci bloku lze k aktuální chybě přistupovat pomocí $_ proměnné nebo $PSItem automatické proměnné. Objekt je typu ErrorRecord.

try { NonsenseString }
catch {
    Write-Host "An error occurred:"
    Write-Host $_
}

Spuštění tohoto skriptu vrátí následující výsledek:

An Error occurred:
The term 'NonsenseString' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.

Existují další vlastnosti, ke kterým lze přistupovat, například ScriptStackTrace, Exceptiona ErrorDetails. Pokud například změníme skript na následující:

try { NonsenseString }
catch {
    Write-Host "An error occurred:"
    Write-Host $_.ScriptStackTrace
}

Výsledek bude podobný následujícímu:

An Error occurred:
at <ScriptBlock>, <No file>: line 2

Uvolnění prostředků pomocí funkce Finally

Pokud chcete uvolnit prostředky používané skriptem, přidejte za finally blok try a catch. Příkazy bloku finally běží bez ohledu na to, jestli try blok narazí na ukončující chybu. PowerShell spustí blok finally před ukončením skriptu nebo před ukončením aktuálního bloku mimo rozsah.

Blok finally se spustí, i když k zastavení skriptu použijete CTRL+C. Blok finally se spustí také v případě, že klíčové slovo exit zastaví skript v rámci bloku catch.

V následujícím příkladu se blok try pokusí stáhnout soubor do složky C:\temp. catch blokuje zpracování chyb, ke kterým dochází během stahování. Blok finally odstraní objekt WebClient a odebere dočasný soubor, pokud existuje.

try {
    $wc = New-Object System.Net.WebClient
    $tempFile = "C:\temp\MyDoc.doc"
    $wc.DownloadFile("https://httpbin.org/MyDoc.doc",$tempFile)
} catch [System.Net.WebException],[System.IO.IOException] {
    "Unable to download MyDoc.doc from https://httpbin.org."
} catch {
    "An error occurred that could not be resolved."
} finally {
    $wc.Dispose()
    if (Test-Path $tempFile) { Remove-Item $tempFile }
}

Viz také