Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Krátký popis
Popisuje typy chyb v PowerShellu a mechanismy pro jejich zpracování.
Dlouhý popis
PowerShell rozlišuje tři kategorie chyb:
- Neukončující chyby
- Chyby ukončující příkazy
- Chyby ukončující skripty
Pochopení rozdílu je nezbytné pro psaní spolehlivých skriptů a modulů, protože každá kategorie má jiné výchozí chování a vyžaduje různé techniky zpracování.
Kromě toho externí (nativní) programy hlásí selhání prostřednictvím ukončovací kódy, které PowerShell sleduje odděleně od vlastního systému chyb.
Typy chyb
Neukončující chyby
Neukončující chyba hlásí problém, ale nezastaví kanál. Příkaz pokračuje ve zpracování následných vstupních objektů. Neukončující chyby se generují pomocí:
- Cmdlet
Write-Error - Metoda
$PSCmdlet.WriteError()v pokročilých funkcích - Rutiny, u jednotlivých vstupních objektů dochází k obnovitelným chybám
PowerShell ve výchozím nastavení zobrazí chybovou zprávu a pokračuje v provádění.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
V tomto příkladu Get-Content hlásí neukončující chybu a noSuchFile.txt pak pokračuje ve zpracování file3.txt.
Neukončující chyby se neaktivují nebo catch ve výchozím nastavení neaktivujítrap.
Chyby ukončující příkazy
Chyba ukončující příkaz zastaví spuštění aktuálního příkazu (kanálu), ale spuštění pokračuje na dalším příkazu ve skriptu. Chyby ukončující příkazy se generují pomocí:
- Metoda
$PSCmdlet.ThrowTerminatingError()v pokročilých funkcích a zkompilovaných rutinách - Chyby modulu, například
CommandNotFoundException(volání příkazu, který neexistuje) aParameterBindingException(neplatné argumenty parametrů) - Volání metody .NET, která vyvolává výjimky, například
[int]::Parse('abc')
# Statement-terminating error: Get-Item fails, but the next statement runs
Get-Item -Path 'C:\NoSuchFile.txt'
Write-Output 'This still runs'
Chyby ukončující příkazy mohou být zachyceny try/catch a trap.
Poznámka:
.ThrowTerminatingError() nekonzultuje -ErrorAction parametr (s výjimkou Break hodnoty, která zadává ladicí program).
$ErrorActionPreference Vztahuje se však na chyby ukončující příkazy prostřednictvím obslužné rutiny na úrovni příkazů modulu. Může například potlačit chybu ukončující příkaz, $ErrorActionPreference = 'SilentlyContinue' aby skript pokračoval v dalším příkazu. Parametr -ErrorAction to nemůže provést. Podrobnosti najdete v tématu $ErrorActionPreference asymetrie.
Chyby ukončující skripty
Chyba ukončující skript uvolní celý zásobník volání. Provádění se úplně zastaví, pokud se chyba nezachytí blokem nebo try/catch příkazemtrap. Chyby ukončující skripty se generují pomocí:
- Klíčové slovo
throw - Parsování chyb (chyby syntaxe, které brání kompilaci skriptu)
- Neukončující chyby eskalované
-ErrorAction Stopnebo$ErrorActionPreference = 'Stop'neukončující kontexty. Další informace naleznete v tématu Jak eskalace funguje. - Určitá selhání kritického modulu
# Script-terminating error: throw unwinds the call stack
function Test-Throw {
throw 'Critical failure'
Write-Output 'This never runs'
}
Test-Throw
Write-Output 'This never runs either (unless caught)'
Klíčové throw slovo ve výchozím nastavení generuje chybu ukončující skript. Však může $ErrorActionPreference potlačitthrow, pokud je nastavena SilentlyContinue nebo .Ignore Při volání pokročilé funkce pomocí -ErrorAction SilentlyContinueparametru se překládá na místní $ErrorActionPreference hodnotu oboru, takže také potlačuje throw uvnitř této funkce.
Poznámka:
I v $ErrorActionPreference = 'Ignore'případě , throw že je potlačeno, stále zaznamenává položku v $Error. Tato Ignore hodnota brání $Error záznamu pouze pro neukončující chyby.
Důležité
Termíny ukončování příkazů a ukončování skriptů popisují rozsah dopadu, nikoli závažnost chyby. Chyba ukončující příkaz zastaví jeden příkaz. Chyba ukončující skript zastaví celý skript a jeho volající. Oba mohou být zachyceny try/catch.
Chyby externího programu
Externí (nativní) programy se přímo neúčastní chybového systému PowerShellu. Hlásí selhání prostřednictvím nenulového ukončovacího kódu, který PowerShell ukládá do $LASTEXITCODE automatické proměnné.
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
Ve výchozím nastavení nenulový ukončovací kód z nativního programu:
- Nastaví
$?na$false -
Nevygeneruje
ErrorRecord$Error -
Neaktivuje ani neaktivuje
catchtrap
PowerShell 7.3 přidal experimentální proměnnou $PSNativeCommandUseErrorActionPreferencepředvoleb, která se stala stabilní funkcí ve verzi 7.4. Když nastavíte tuto proměnnou na $true, způsobí, že nenulový ukončovací kód vygeneruje neukončující chybu , jejíž zpráva uvádí konkrétní ukončovací kód (a NativeCommandExitException). Tato chyba respektuje $ErrorActionPreference, takže nastavení na Stop podporu chyby na chybu ukončující skript, který lze zachytit try/catchs .
Proměnné stavu chyby
PowerShell udržuje několik automatických proměnných, které odrážejí aktuální stav chyby.
$?
Obsahuje $true , jestli poslední operace proběhla úspěšně a $false jestli došlo k nějaké chybě (neukončující nebo ukončující). Pro nativní příkazy $? je nastavena na základě ukončovací kód: $true pro ukončovací kód 0, $false jinak.
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
Obsahuje ArrayList nejnovější záznamy o chybách s nejnovější chybou v indexu 0. Seznam obsahuje až $MaximumErrorCount položky (výchozí 256).
Všechny ukončující chyby se přidají do $Errorsouboru . U ukončování chyb potlačí zobrazení, Ignore ale stále zaznamenává chybu v $Error. Všechny neukončující chyby se přidají, $Error pokud -ErrorAction Ignore nejsou použity pro neukončující chyby, které brání zobrazení i nahrávání.
$LASTEXITCODE
Obsahuje ukončovací kód posledního nativního programu, který se spustil. Hodnota 0 konvenčně označuje úspěch. Jakákoli nenulová hodnota značí selhání. Tato proměnná není ovlivněna chybami rutin PowerShellu.
Řízení chování chyb
Společný -ErrorAction parametr
Společný -ErrorAction parametr přepíše $ErrorActionPreference jeden příkaz. Určuje, jak PowerShell reaguje na neukončující chyby z daného příkazu.
| Hodnota | Chování |
|---|---|
Continue |
Zobrazení chyby a pokračování (výchozí) |
SilentlyContinue |
Potlačit zobrazení, přidat do $Error, pokračovat |
Ignore |
Potlačení zobrazení a nepřidávejte do $Error |
Stop |
Eskalace k ukončovací chybě (viz Postup eskalace) |
Inquire |
Výzva k zadání rozhodnutí uživatele |
Break |
Zadejte ladicí program. |
-ErrorAction nemění chování chyb generovaných funkcí $PSCmdlet.ThrowTerminatingError(). Tyto chyby jsou vždy ukončující příkazy bez ohledu na předvolbu volajícího.
Proměnná $ErrorActionPreference
Proměnná $ErrorActionPreference předvoleb se vztahuje na všechny příkazy v aktuálním oboru a podřízených oborech. Přijímá stejné hodnoty jako -ErrorAction.
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
Pokud -ErrorAction je zadán v příkazu, má přednost před $ErrorActionPreference tímto příkazem.
Jak eskalace funguje
Pokud -ErrorAction Stop nebo $ErrorActionPreference = 'Stop' je v platnosti, PowerShell převede neukončující chyby na ukončující chyby pomocí následujícího mechanismu:
- Rutina interně volá
WriteError(), aby vygeneruje neukončující chybu. - Modul zkontroluje efektivní
ErrorActionpředvolbu příkazu. - Vzhledem k tomu, že předvolba je
Stop, modul vytvoříActionPreferenceStopException, který zabalí původní záznam chyby. - Jsou-li zachyceny
catch, původní informace o chybě jsou přístupné prostřednictvím$_.Exception.ErrorRecord.
Rozsah eskalované chyby závisí na kontextu:
- V jiných než pokročilých skriptech, funkcích nebo blocích skriptu se nastavení
$ErrorActionPreference = 'Stop'eskaluje na chybu ukončující skript . Chyba se rozšíří do zásobníku volání. - V pokročilých funkcích a blocích skriptů (těch s
[CmdletBinding()]) zůstává chyba ukončující příkaz. Provádění pokračuje po volání na další příkaz. - Předání
-ErrorAction Stopdo pokročilé funkce má stejný účinek jako nastavení$ErrorActionPreference = 'Stop'uvnitř, protože-ErrorActionse překládá na místní$ErrorActionPreferencehodnotu oboru.
Příklady eskalace
Jiné než pokročilé: ukončování skriptu (po) se netiskne.
& { param() $ErrorActionPreference = 'Stop' 1/0 # Divide by zero error } 2>$null 'after'ADVANCED: ukončování příkazů ('after' DO print)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop' 1/0 # Divide by zero error } 2>$null 'after'Bez
-ErrorAction Stop: neukončování, catch se nespustítry { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }S
-ErrorAction Stop: eskalováno na ukončenítry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
Eskalované chyby mohou být zachyceny jejich původním typem výjimky. Modul rozbalí ActionPreferenceStopException základní výjimku:
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
Asymetrie $ErrorActionPreference
Parametr -ErrorAction a $ErrorActionPreference proměnná se chovají jinak s ukončovacími chybami. Je důležité pochopit tuto asymetrii:
-ErrorActionmá vliv pouze na neukončující chyby. Při volání$PSCmdlet.ThrowTerminatingError()-ErrorActionrutiny se parametr ignoruje (s výjimkouBreak, který zadá ladicí program). Chyba se vždy vyvolá.$ErrorActionPreferenceovlivňuje neukončující i ukončovací chyby. Obslužná rutina chyby na úrovni příkazu modulu čte$ErrorActionPreference(nikoli-ErrorActionparametr) a může potlačit chybu ukončující příkaz, pokud jeSilentlyContinuehodnota neboIgnore.
function Test-Asymmetry {
[CmdletBinding()]
param()
$er = [System.Management.Automation.ErrorRecord]::new(
[System.InvalidOperationException]::new('test error'),
'TestError',
[System.Management.Automation.ErrorCategory]::InvalidOperation,
$null
)
$PSCmdlet.ThrowTerminatingError($er)
}
# -ErrorAction SilentlyContinue does NOT suppress the error:
Test-Asymmetry -ErrorAction SilentlyContinue # Error is still thrown
# $ErrorActionPreference DOES suppress the error:
$ErrorActionPreference = 'SilentlyContinue'
Test-Asymmetry # Error is silently suppressed, script continues
$ErrorActionPreference = 'Continue'
Důležité
$ErrorActionPreference nemůže potlačit chyby, které jsou SuppressPromptInInterpreter nastavené na true. Tyto proměnné se vždy šíří bez ohledu na proměnnou předvoleb. Mezi příklady tohoto typu chyby patří:
-
ActionPreferenceStopExceptionz-ErrorAction Stopeskalace - Chyby v metodách třídy PowerShellu
PipelineStoppedException
Řešte chyby
try/catch/finally
Slouží try/catch/finally ke zpracování chyb ukončování příkazů a ukončování skriptů. Pokud dojde k chybě uvnitř try bloku, PowerShell vyhledá odpovídající catch blok. Blok finally se vždy spustí bez ohledu na to, jestli došlo k chybě.
try {
$result = Get-Content -Path 'data.txt' -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning 'Data file not found, using defaults.'
$result = 'default'
}
catch {
Write-Warning "Unexpected error: $_"
}
finally {
Write-Verbose 'Cleanup complete.' -Verbose
}
try Uvnitř bloku modul nastaví interní příznak, který způsobí neukončující chyby eskalované -ErrorAction Stop nebo $ErrorActionPreference = 'Stop' se rozšíří do catch bloku. Toto chování je navržené, ne zvláštní případ.
Úplné podrobnosti o syntaxi najdete v tématu about_Try_Catch_Finally.
trap
Příkaz trap zpracovává ukončovací chyby na úrovni oboru. Pokud dojde k chybě kdekoli v nadřazeném oboru, blok se trap spustí.
-
Výchozí (ne
breaknebocontinue): Chyba se zobrazí a spuštění pokračuje v dalším příkazu za příkazem, který způsobil chybu. -
continuein the trap: Suppresses the error message and resumes at the next statement. -
breakv soutisku: Chyba se rozšíří do nadřazeného oboru.
trap [System.Management.Automation.CommandNotFoundException] {
Write-Warning "Command not found: $($_.TargetObject)"
continue
}
NonsenseCommand # Trap fires, execution continues
Write-Output 'This runs because the trap used continue'
Úplné podrobnosti o syntaxi najdete v tématu about_Trap.
Hlášení chyb ve funkcích a skriptech
Při psaní funkcí a skriptů zvolte mechanismus zasílání zpráv o chybách, který odpovídá závažnosti selhání.
Neukončující – použití Write-Error
Používá Write-Error se, když může funkce pokračovat ve zpracování jiného vstupu. To je vhodné pro funkce kanálu, které zpracovávají více objektů a dochází k chybám u jednotlivých položek.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Poznámka:
V pokročilých funkcích (těch, které [CmdletBinding()]mají) místo $PSCmdlet.WriteError()Write-Error toho, abyste měli jistotu, že $? je správně nastavená $false na rozsah volajícího. Rutina Write-Error není vždy správně nastavená $? .
Ukončování příkazů – use $PSCmdlet.ThrowTerminatingError()
Použijte $PSCmdlet.ThrowTerminatingError() , když funkce nemůže pokračovat vůbec, ale volající by se měl rozhodnout, jak se má selhání zpracovat. Toto je doporučený přístup v pokročilých funkcích.
function Get-Config {
[CmdletBinding()]
param([string]$Path)
if (-not (Test-Path $Path)) {
$er = [System.Management.Automation.ErrorRecord]::new(
[System.IO.FileNotFoundException]::new("Config file not found: $Path"),
'ConfigNotFound',
[System.Management.Automation.ErrorCategory]::ObjectNotFound,
$Path
)
$PSCmdlet.ThrowTerminatingError($er)
}
Get-Content $Path | ConvertFrom-Json
}
Jakmile tato chyba funkci opustí, volající ji ve výchozím nastavení považuje za neukončující chybu. Volající ho může eskalovat s -ErrorAction Stop.
Ukončování skriptů – použití throw
Použijte throw , když obnovení není možné a celý skript by se měl zastavit.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Jaký mechanismus se má použít
- Při zpracování více vstupů, kde některé mohou selhat, použít
Write-Errornebo$PSCmdlet.WriteError(). - Pokud funkce nemůže pokračovat, použijte
$PSCmdlet.ThrowTerminatingError()a nechte volajícího rozhodnout, jak ji zpracovat. - Pokud se celý skript musí okamžitě zastavit, použijte
throw.
Souhrn typů chyb
Následující tabulky shrnují vlastnosti a chování různých typů chyb v PowerShellu.
Neukončující chyba
Neukončující chyby mohou být generovány Write-Error nebo $PSCmdlet.WriteError().
| Vlastnost | Description |
|---|---|
| Rozsah dopadu | Kanál pokračuje |
Zachyceno catch |
Ne (pokud není eskalováno) |
Zachyceno trap |
Ne (pokud není eskalováno) |
Přidáno do $Error |
Ano (pokud Ignore) |
Nastaví $? na $false |
Ano |
Ovlivněno -ErrorAction |
Ano |
Ovlivněno $ErrorActionPreference |
Ano |
Chyba ukončení příkazu
Chyby ukončující příkazy mohou být generovány chybami ThrowTerminatingError()modulu, výjimkami metod .NET nebo -ErrorAction Stop v pokročilých kontextech.
| Vlastnost | Description |
|---|---|
| Rozsah dopadu | Aktuální příkaz se zastaví; skript pokračuje |
Zachyceno catch |
Ano |
Zachyceno trap |
Ano |
Přidáno do $Error |
Ano |
Nastaví $? na $false |
Ano |
Ovlivněno -ErrorAction |
Ne (Break pouze) |
Ovlivněno $ErrorActionPreference |
Ano (může potlačit) |
Chyba ukončování skriptu
Chyby ukončující skripty můžou být generovány throw, parsovat chyby nebo -ErrorAction Stop v nepokročilejších kontextech.
| Vlastnost | Description |
|---|---|
| Rozsah dopadu | Odvíjení zásobníku volání |
Zachyceno catch |
Ano |
Zachyceno trap |
Ano |
Přidáno do $Error |
Ano |
Nastaví $? na $false |
Ano |
Ovlivněno -ErrorAction |
Ne |
Ovlivněno $ErrorActionPreference |
throw: Ano (může potlačit) |
Ovlivněno $ErrorActionPreference |
Eskalace: závisí na kontextu. |