Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Breve descrição
Descreve os tipos de erros no PowerShell e os mecanismos para os tratar.
Descrição longa
O PowerShell distingue três categorias de erros:
- Erros não terminantes
- Erros de terminação de instruções
- Erros de terminação de script
Compreender a distinção é essencial para escrever scripts e módulos fiáveis, porque cada categoria tem comportamentos padrão diferentes e requer técnicas de tratamento distintas.
Além disso, programas externos (nativos) reportam falhas através de códigos de saída, que o PowerShell monitoriza separadamente do seu próprio sistema de erros.
Tipos de erros
Erros não terminantes
Um erro de não terminação reporta um problema, mas não para o pipeline. O comando continua a processar os objetos de entrada subsequentes. Os erros não terminantes são gerados por:
- O
Write-Errorcmdlet - O
$PSCmdlet.WriteError()método em funções avançadas - Cmdlets que encontram falhas recuperáveis em objetos de entrada individuais
Por defeito, o PowerShell mostra a mensagem de erro e continua a execução.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
Neste exemplo, Get-Content reporta um erro de não terminação para noSuchFile.txt e depois continua a processar file3.txt.
Erros de não terminação não são acionados catch nem trap por defeito.
Erros de terminação de instruções
Um erro de terminação de instrução impede que a instrução atual (pipeline) seja executada, mas a execução continua na próxima instrução do script. Erros de terminação de instrução são gerados por:
- O
$PSCmdlet.ThrowTerminatingError()método em funções avançadas e cmdlets compilados - Erros do motor como
CommandNotFoundException(chamar um comando que não existe) eParameterBindingException(argumentos de parâmetros inválidos) - .NET que lançam exceções, como
[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'
Erros de terminação de instruções podem ser detetados por try/catch e trap.
Observação
.ThrowTerminatingError() não consulta o -ErrorAction parâmetro (exceto o Break valor, que entra no depurador). No entanto, $ErrorActionPreferenceaplica-se a erros de terminação de instruções através do handler ao nível da instrução do motor. Por exemplo, $ErrorActionPreference = 'SilentlyContinue' pode suprimir um erro de terminação de instrução para que o script continue na próxima instrução. O -ErrorAction parâmetro não consegue fazer isto. Para mais detalhes, veja A assimetria $ErrorActionPreference.
Erros de terminação de script
Um erro de terminação de script desenrola toda a pilha de chamadas. A execução para completamente, a menos que o erro seja detetado por um try/catch bloco ou trap sentença. Os erros de terminação de scripts são gerados por:
- A palavra-chave
throw - Erros de análise (erros de sintaxe que impedem a compilação do script)
- Erros não terminantes escalados por
-ErrorAction Stopou$ErrorActionPreference = 'Stop'em contextos não avançados. Para mais informações, veja Como funciona a escalada. - Certas falhas críticas no motor
# 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)'
A throw palavra-chave gera um erro de terminação de script por defeito. No entanto, $ErrorActionPreferencepode suprimir throw quando definido como SilentlyContinue ou Ignore. Ao chamar uma função avançada com -ErrorAction SilentlyContinue, o parâmetro traduz-se num valor local $ErrorActionPreference no escopo, pelo que também suprime throw dentro dessa função.
Observação
Mesmo com $ErrorActionPreference = 'Ignore', um throw que está suprimido ainda regista uma entrada em $Error. O Ignore valor apenas impede $Error a gravação de erros que não terminam .
Importante
Os termos terminação de instrução e terminação de script descrevem o âmbito do impacto, não a gravidade do erro. Um erro de terminação de instrução para uma afirmação. Um erro de terminação de script para todo o script e os seus chamadores. Ambos podem ser capturados por try/catch.
Erros de programas externos
Programas externos (nativos) não participam diretamente no sistema de erros do PowerShell. Reportam a falha através de um código de saída diferente de zero, que o PowerShell armazena na $LASTEXITCODE variável automática.
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
Por defeito, um código de saída diferente de zero de um programa nativo:
- Conjuntos
$?para$false -
Não gera um
ErrorRecordem$Error -
Não desencadeia
catchoutrap
O PowerShell 7.3 adicionou a variável $PSNativeCommandUseErrorActionPreferencede preferência experimental , que se tornou uma funcionalidade estável na 7.4. Quando define esta variável para $true, faz com que um código de saída não nulo emita um erro de não terminação cuja mensagem indica o código de saída específico (a NativeCommandExitException). Este erro respeita $ErrorActionPreference, pelo que defini-lo Stop para promove o erro para um erro de terminação de script que pode ser apanhado com/trycatch .
Variáveis de estado de erro
O PowerShell mantém várias variáveis automáticas que refletem o estado atual do erro.
$?
Contém $true se a última operação foi bem-sucedida e $false se produziu algum erro (não terminando ou terminando). Para comandos nativos, $? é definido com base no código de saída: $true para o código 0de saída , $false caso contrário.
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
E ArrayList que armazena os registos de erro mais recentes, com o erro mais recente no índice 0. A lista mantém-se até $MaximumErrorCount entradas (por defeito 256).
Todos os erros de terminação são adicionados a $Error. Para terminar erros, Ignore suprime a visualização mas ainda regista o erro em $Error. Todos os que não terminam são adicionados a $Error menos que -ErrorAction Ignore sejam usados em erros que não terminam, o que impede tanto a visualização como a gravação.
$LASTEXITCODE
Contém o código de saída do último programa nativo que foi executado. Um valor de 0 indica convencionalmente sucesso. Qualquer valor diferente de zero indica falha. Esta variável não é afetada por erros do cmdlet do PowerShell.
Comportamento de erro de controlo
O -ErrorAction parâmetro comum
O -ErrorAction parâmetro comum sobrepõe-se $ErrorActionPreference a um único comando. Controla como o PowerShell responde a erros que não terminam desse comando.
| Value | Comportamento |
|---|---|
Continue |
Mostrar o erro e continuar (predefinido) |
SilentlyContinue |
Suprimir exibição, adicionar a $Error, continuar |
Ignore |
Suprimir o ecrã e não adicionar a $Error |
Stop |
Escalar para um erro de terminação (ver Como funciona a escalonamento) |
Inquire |
Incentive o utilizador a tomar uma decisão |
Break |
Entra o depurador |
-ErrorAction não altera o comportamento dos erros gerados por $PSCmdlet.ThrowTerminatingError(). Esses erros terminam sempre a instrução, independentemente da preferência do chamador.
A $ErrorActionPreference variável
A $ErrorActionPreference variável de preferência aplica-se a todos os comandos no âmbito atual e filho. Aceita os mesmos valores que -ErrorAction.
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
Quando -ErrorAction é especificado num comando, tem precedência sobre $ErrorActionPreference esse comando.
Como funciona a escalada
Quando -ErrorAction Stop ou $ErrorActionPreference = 'Stop' está em vigor, o PowerShell converte erros de não terminação em erros de terminação usando o seguinte mecanismo:
- Um cmdlet chama
WriteError()internamente para emitir um erro de não terminação. - O motor verifica a preferência efetiva
ErrorActionpelo comando. - Como a preferência é
Stop, o motor cria umActionPreferenceStopExceptionque envolve o registo de erro original. - Se capturado por
catch, a informação original de erro é acessível através de$_.Exception.ErrorRecord.
O âmbito do erro escalado depende do contexto:
- Em scripts, funções ou blocos de script não avançados , a definição
$ErrorActionPreference = 'Stop'escala para um erro que termina o script . O erro propaga-se pela pilha de chamadas. - Em funções avançadas e blocos de script (aqueles com
[CmdletBinding()]), o erro mantém-se a terminar a instrução. A execução continua na declaração seguinte após a chamada. - Passar
-ErrorAction Stoppara uma função avançada tem o mesmo efeito que definir$ErrorActionPreference = 'Stop'dentro dela, porque-ErrorActionse traduz num valor local$ErrorActionPreferenceno escopo.
Exemplos de escalada
NÃO avançado: terminação de script ('after' NÃO imprime)
& { param() $ErrorActionPreference = 'Stop' Get-Item 'NoSuchPath' } 2>$null 'after'ADVANCED: terminação de instrução ('after' DOES print)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null 'after'Sem
-ErrorAction Stop: não terminando, a captura não corretry { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }Com
-ErrorAction Stop: escalou para terminartry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
Erros escalonados podem ser detetados pelo seu tipo de exceção original. O motor desdobra o ActionPreferenceStopException para encontrar a exceção subjacente:
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
A $ErrorActionPreference assimetria
O -ErrorAction parâmetro e a $ErrorActionPreference variável comportam-se de forma diferente com erros de terminação. É importante compreender esta assimetria:
-ErrorActionSó afeta erros que não terminam . Quando um cmdlet chama$PSCmdlet.ThrowTerminatingError(), o-ErrorActionparâmetro é ignorado (exceto ,Breakque entra no depurador). O erro é sempre lançado.$ErrorActionPreferenceafeta tanto erros de não terminação como de terminação de sentença. O manipulador de erro ao nível da instrução do motor lê$ErrorActionPreference(não o-ErrorActionparâmetro) e pode suprimir um erro de terminação de instruções quando o valor éSilentlyContinueouIgnore.
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'
Importante
$ErrorActionPreference não é possível suprimir erros que tenham SuppressPromptInInterpreter definido para true. Estas propagam-se sempre independentemente da variável de preferência. Exemplos deste tipo de erro incluem:
-
ActionPreferenceStopExceptionA partir da-ErrorAction Stopescalada - Erros dentro dos métodos de classe PowerShell
PipelineStoppedException
Lidar com erros
try/catch/finally
Use try/catch/finally para lidar com erros de terminação de instruções e de terminação de scripts. Quando ocorre um erro dentro de um try bloco, o PowerShell procura um bloco correspondente catch . O finally bloco corre sempre, independentemente de ter ocorrido ou não um erro.
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
}
Dentro de um try bloco, o motor define uma bandeira interna que provoca erros de não terminação escalados por -ErrorAction Stop ou $ErrorActionPreference = 'Stop' que se propagam para o bloco catch . Isto é um comportamento desenhado, não um caso especial.
Para detalhes completos da sintaxe, veja about_Try_Catch_Finally.
trap
A trap instrução trata de erros de terminação ao nível do âmbito. Quando ocorre um erro em qualquer parte do âmbito de encerramento, o trap bloco executa-se.
-
Default (não
breakoucontinue): O erro é exibido e a execução continua na próxima instrução após aquela que causou o erro. -
continuena armadilha: Suprime a mensagem de erro e retoma na próxima instrução. -
breakna armadilha: O erro propaga-se para o âmbito pai.
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'
Para detalhes completos da sintaxe, veja about_Trap.
Relatórios de erros em funções e scripts
Ao escrever funções e scripts, escolha o mecanismo de reporte de erros que corresponda à gravidade da falha.
Não-terminação - utilização Write-Error
Use Write-Error quando a função puder continuar a processar outros inputs. Isto é apropriado para funções de pipeline que processam múltiplos objetos e enfrentam falhas em itens individuais.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Observação
Em funções avançadas (aquelas com [CmdletBinding()]), use $PSCmdlet.WriteError() em vez de Write-Error para garantir que $? está corretamente definido como $false no âmbito do chamador. O Write-Error cmdlet nem sempre se ajusta $? corretamente.
Terminação de instruções - utilização $PSCmdlet.ThrowTerminatingError()
$PSCmdlet.ThrowTerminatingError() Use quando a função não puder continuar de todo, mas o chamador deve decidir como lidar com a falha. Esta é a abordagem recomendada em funções avançadas.
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
}
Depois de o erro sair da função, o chamador trata-o como um erro não terminante por defeito. O interlocutor pode escalar a situação com -ErrorAction Stop.
Terminação de scripts - utilização throw
Usa throw quando a recuperação não for possível e o script inteiro deve parar.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Que mecanismo usar
- Ao processar múltiplas entradas onde algumas podem falhar, use
Write-Errorou$PSCmdlet.WriteError(). - Se a função não puder continuar, use
$PSCmdlet.ThrowTerminatingError()e deixe que o interlocutor decida como a gerir. - Se o script inteiro tiver de parar imediatamente, use
throw.
Resumo dos tipos de erro
As tabelas seguintes resumem as propriedades e comportamentos dos diferentes tipos de erro no PowerShell.
Erro de não terminação
Erros não terminantes podem ser gerados por Write-Error ou $PSCmdlet.WriteError().
| Attribute | Descrição |
|---|---|
| Dimensão do impacto | O oleoduto continua |
Apanhado por catch |
Não (a não ser que seja escalado) |
Apanhado por trap |
Não (a não ser que seja escalado) |
Acrescentado a $Error |
Sim (a menos que Ignore) |
Conjuntos $? para $false |
Sim |
Afetado por -ErrorAction |
Sim |
Afetado por $ErrorActionPreference |
Sim |
Erro de terminação de instruções
Erros de terminação de instruções podem ser gerados por ThrowTerminatingError(), erros do motor, exceções do método .NET ou -ErrorAction Stop em contextos avançados.
| Attribute | Descrição |
|---|---|
| Dimensão do impacto | A declaração atual para; O guião continua |
Apanhado por catch |
Sim |
Apanhado por trap |
Sim |
Acrescentado a $Error |
Sim |
Conjuntos $? para $false |
Sim |
Afetado por -ErrorAction |
Não (Break apenas) |
Afetado por $ErrorActionPreference |
Sim (pode suprimir) |
Erro de terminação de script
Erros de terminação de script podem ser gerados por throw, erros de análise ou -ErrorAction Stop em contextos não avançados.
| Attribute | Descrição |
|---|---|
| Dimensão do impacto | Desenrolar a pilha de chamadas |
Apanhado por catch |
Sim |
Apanhado por trap |
Sim |
Acrescentado a $Error |
Sim |
Conjuntos $? para $false |
Sim |
Afetado por -ErrorAction |
No |
Afetado por $ErrorActionPreference |
throw: Sim (pode suprimir) |
Afetado por $ErrorActionPreference |
Escalado: depende do contexto |