Compartilhar via


about_Error_Handling

Descrição curta

Descreve os tipos de erros no PowerShell e os mecanismos para lidar com eles.

Descrição longa

O PowerShell distingue três categorias de erros:

  • Erros de não terminação
  • Erros de encerramento de instrução
  • Erros de encerramento de script

Entender a distinção é essencial para escrever scripts e módulos confiáveis, pois cada categoria tem um comportamento padrão diferente e requer diferentes técnicas de tratamento.

Além disso, programas externos (nativos) relatam falha por meio de códigos de saída, que o PowerShell rastreia separadamente de seu próprio sistema de erros.

Tipos de erros

Erros de não terminação

Um erro de não encerramento relata um problema, mas não interrompe o pipeline. O comando continua processando objetos de entrada subsequentes. Erros de não terminação são gerados por:

  • O Write-Error cmdlet
  • O $PSCmdlet.WriteError() método em funções avançadas
  • Cmdlets que encontram falhas recuperáveis em objetos de entrada individuais

Por padrão, o PowerShell exibe 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 relata um erro noSuchFile.txt de não terminação e, em seguida, continua o processamento file3.txt.

Erros de não terminação não são disparados catch ou trap por padrão.

Erros de encerramento de instrução

Um erro de encerramento de instrução impede a execução da instrução atual (pipeline), mas a execução continua na próxima instrução no script. Os erros de encerramento de instrução são gerados por:

  • O $PSCmdlet.ThrowTerminatingError() método em funções avançadas e cmdlets compilados
  • Erros de mecanismo, como CommandNotFoundException (chamar um comando que não existe) e ParameterBindingException (argumentos de parâmetro inválidos)
  • Chamadas de método .NET que geram 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 encerramento de instrução podem ser capturados por try/catch e trap.

Observação

.ThrowTerminatingError() não consulta o -ErrorAction parâmetro (exceto pelo Break valor, que insere o depurador). No entanto, $ErrorActionPreferenceaplica-se a erros de encerramento de instrução por meio do manipulador de nível de instrução do mecanismo. Por exemplo, $ErrorActionPreference = 'SilentlyContinue' pode suprimir um erro de encerramento de instrução para que o script continue na próxima instrução. O -ErrorAction parâmetro não pode fazer isso. Para obter detalhes, consulte A $ErrorActionPreference assimetria.

Erros de encerramento de script

Um erro de encerramento de script desenrola toda a pilha de chamadas. A execução é interrompida completamente, a menos que o erro seja capturado por um try/catch bloco ou trap instrução. Os erros de encerramento de script são gerados por:

  • A palavra-chave throw
  • Analisar erros (erros de sintaxe que impedem que o script seja compilado)
  • Erros de não terminação escalonado por -ErrorAction Stop ou $ErrorActionPreference = 'Stop' em contextos não avançados. Para obter mais informações, consulte Como funciona o escalonamento.
  • Determinadas falhas críticas do mecanismo
# 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 encerramento de script por padrão. No entanto, $ErrorActionPreferencepode suprimir throw quando definido como SilentlyContinue ou Ignore. Ao chamar uma função avançada com -ErrorAction SilentlyContinue, o parâmetro se traduz em um valor local $ErrorActionPreference de escopo, portanto, ele também suprime throw dentro dessa função.

Observação

Mesmo com $ErrorActionPreference = 'Ignore', um throw que é suprimido ainda registra uma entrada em $Error. O Ignore valor impede apenas a $Error gravação para erros de não terminação .

Importante

Os termos de terminação de instrução e encerramento de script descrevem o escopo do impacto, não a gravidade do erro. Um erro de encerramento de instrução interrompe uma instrução. Um erro de encerramento de script interrompe todo o script e seus chamadores. Ambos podem ser pegos por try/catch.

Erros de programa externo

Programas externos (nativos) não participam diretamente do sistema de erros do PowerShell. Eles relatam falha por meio 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 padrão, um código de saída diferente de zero de um programa nativo:

  • Define $? como $false
  • Não gera uma entrada ErrorRecord$Error
  • Não disparacatch ou trap

O PowerShell 7.3 adicionou a variável $PSNativeCommandUseErrorActionPreferencede preferência experimental, que se tornou um recurso estável na versão 7.4. Quando você define essa variável como $true, ela faz com que um código de saída diferente de zero emita um erro de não terminação cuja mensagem declara o código de saída específico (a NativeCommandExitException). Esse erro respeita $ErrorActionPreference, portanto, defini-lo para Stop promover o erro para um erro de encerramento de script que pode ser capturado com try/catch.

Variáveis de estado de erro

O PowerShell mantém várias variáveis automáticas que refletem o estado de erro atual.

$?

Contém $true se a última operação foi bem-sucedida e $false se ela produziu algum erro (não terminação ou terminação). 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

Um ArrayList que armazena os registros de erro mais recentes, com o erro mais recente no índice 0. A lista contém $MaximumErrorCount entradas (padrão 256).

Todos os erros de término são adicionados a $Error. Para encerrar erros, suprime a exibição, Ignore mas ainda registra o erro em $Error. Todas as não terminações são adicionadas, $Error a menos que sejam usadas -ErrorAction Ignore em erros de não terminação, o que impede a exibição e a gravação.

$LASTEXITCODE

Contém o código de saída do último programa nativo executado. Um valor de 0 convencionalmente indica êxito. Qualquer valor diferente de zero indica falha. Essa variável não é afetada por erros de cmdlet do PowerShell.

Comportamento de erro de controle

O -ErrorAction parâmetro comum

O -ErrorAction parâmetro comum substitui $ErrorActionPreference um único comando. Ele controla como o PowerShell responde a erros de não terminação desse comando.

Valor Comportamento
Continue Exibir o erro e continuar (padrão)
SilentlyContinue Suprimir exibição, adicionar a $Error, continuar
Ignore Suprimir exibição e não adicionar a $Error
Stop Escalonar para um erro de término (veja como funciona o escalonamento)
Inquire Solicitar ao usuário uma decisão
Break Insira o depurador

-ErrorAction não altera o comportamento dos erros gerados por $PSCmdlet.ThrowTerminatingError(). Esses erros estão sempre encerrando a instrução, independentemente da preferência do chamador.

A $ErrorActionPreference variável

A $ErrorActionPreference variável de preferência se aplica a todos os comandos no escopo atual e nos escopos filho. Ele 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 em um comando, ele tem precedência $ErrorActionPreference para esse comando.

Como funciona o escalonamento

Quando -ErrorAction Stop ou $ErrorActionPreference = 'Stop' estiver em vigor, o PowerShell converte erros de não terminação em erros de encerramento usando o seguinte mecanismo:

  1. Um cmdlet chama WriteError() internamente para emitir um erro de não terminação.
  2. O mecanismo verifica a preferência efetiva ErrorAction pelo comando.
  3. Como a preferência é Stop, o mecanismo cria um ActionPreferenceStopException que encapsula o registro de erro original.
  4. Se forem capturadas, catchas informações de erro originais poderão ser acessadas por meio $_.Exception.ErrorRecordde .

O escopo do erro escalonado depende do contexto:

  • Em scripts, funções ou blocos de script não avançados , a configuração $ErrorActionPreference = 'Stop' é escalonada para um erro de encerramento de script . O erro propaga a pilha de chamadas.
  • Em funções avançadas e blocos de script (aqueles com [CmdletBinding()]), o erro permanece terminado por instrução. A execução continua na próxima instrução após a chamada.
  • Passar -ErrorAction Stop para uma função avançada tem o mesmo efeito que a configuração $ErrorActionPreference = 'Stop' dentro dela, pois -ErrorAction se traduz em um valor local $ErrorActionPreference de escopo.

Exemplos de escalonamento

  • NÃO avançado: script-terminating ('after' não imprime)

    & {
        param()
        $ErrorActionPreference = 'Stop'
        Get-Item 'NoSuchPath'
    } 2>$null
    'after'
    
  • ADVANCED: statement-terminating ('after' DOES print)

    & {
        [CmdletBinding()]
        param()
        $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath'
    } 2>$null
    'after'
    
  • Sem -ErrorAction Stop: não terminação, a captura não é executada

    try {
        Write-Error 'This is non-terminating'
        Write-Output 'Execution continues'
    } catch {
        Write-Output "Caught: $_"   # Not reached
    }
    
  • Com -ErrorAction Stop: escalonado para terminação

    try {
        Write-Error 'This becomes terminating' -ErrorAction Stop
    } catch {
        Write-Output "Caught: $_"   # Reached
    }
    

Erros escalonado podem ser capturados pelo tipo de exceção original. O mecanismo desembrulha a ActionPreferenceStopException exceção subjacente para localizar:

try {
    Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
    Write-Output "File not found: $($_.Exception.Message)"
}

A $ErrorActionPreference assímetria

O -ErrorAction parâmetro e a $ErrorActionPreference variável se comportam de forma diferente com erros de encerramento. É importante entender essa assímetria:

  • -ErrorAction afeta apenas erros de não terminação . Quando um cmdlet chama $PSCmdlet.ThrowTerminatingError(), o -ErrorAction parâmetro é ignorado (exceto por Break, que insere o depurador). O erro é sempre gerado.

  • $ErrorActionPreference afeta erros de não terminação e terminação de instrução. O manipulador de erros no nível da instrução do mecanismo lê $ErrorActionPreference (não o -ErrorAction parâmetro) e pode suprimir um erro de encerramento de instrução quando o valor é SilentlyContinue ou Ignore.

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 foram SuppressPromptInInterpreter definidos como true. Elas sempre se propagam independentemente da variável de preferência. Exemplos desse tipo de erro incluem:

  • ActionPreferenceStopException do -ErrorAction Stop escalonamento
  • Erros dentro dos métodos de classe do PowerShell
  • PipelineStoppedException

Gerenciar erros

try/catch/finally

Use try/catch/finally para lidar com erros de encerramento de instrução e de encerramento de script. Quando ocorre um erro dentro de um try bloco, o PowerShell procura um bloco correspondente catch . O finally bloco sempre é executado, se ocorreu 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 mecanismo define um sinalizador interno que causa erros de não terminação escalonadas ou -ErrorAction Stop$ErrorActionPreference = 'Stop' propagados para o catch bloco. Esse é um comportamento projetado, não um caso especial.

Para obter detalhes de sintaxe completa, consulte about_Try_Catch_Finally.

trap

A trap instrução lida com erros de encerramento no nível do escopo. Quando ocorre um erro em qualquer lugar no escopo delimitador, o trap bloco é executado.

  • Padrão (não break ou continue): o erro é exibido e a execução continua na próxima instrução após a que causou o erro.
  • continue na armadilha: suprime a mensagem de erro e será retomada na próxima instrução.
  • break na armadilha: o erro se propaga para o escopo 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 obter detalhes de sintaxe completa, consulte about_Trap.

Relatando erros em funções e scripts

Ao escrever funções e scripts, escolha o mecanismo de relatório de erros que corresponde à gravidade da falha.

Não terminação – use Write-Error

Use Write-Error quando a função puder continuar processando outras entradas. Isso é apropriado para funções de pipeline que processam vários objetos e encontram 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 garantir que $? isso seja definido $false corretamente no escopo do chamador. O Write-Error cmdlet nem sempre é definido $? corretamente.

Terminação de instrução – usar $PSCmdlet.ThrowTerminatingError()

Use $PSCmdlet.ThrowTerminatingError() quando a função não puder continuar, mas o chamador deve decidir como lidar com a falha. Essa é 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 que o erro deixa a função, o chamador a trata como um erro de não encerramento por padrão. O chamador pode escaloná-lo com -ErrorAction Stop.

Terminação de script – usar throw

Use throw quando a recuperação não for possível e todo o script deve parar.

$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
    ConvertFrom-Json

if (-not $config) {
    throw 'Cannot proceed without a valid configuration file.'
}

Qual mecanismo usar

  • Ao processar várias entradas em que algumas podem falhar, usar Write-Error ou $PSCmdlet.WriteError().
  • Se a função não puder continuar, use $PSCmdlet.ThrowTerminatingError() e permita que o chamador decida como lidar com ela.
  • Se o script inteiro precisar parar imediatamente, use throw.

Resumo dos tipos de erro

As tabelas a seguir resumem as propriedades e os comportamentos dos diferentes tipos de erro no PowerShell.

Erro de não encerramento

Erros de não terminação podem ser gerados por Write-Error ou $PSCmdlet.WriteError().

Attribute Descrição
Âmbito do impacto O pipeline continua
Capturado por catch Não (a menos que escalonado)
Capturado por trap Não (a menos que escalonado)
Adicionado a $Error Sim (a menos Ignoreque )
Define $? como $false Sim
Afetado por -ErrorAction Sim
Afetado por $ErrorActionPreference Sim

Erro de encerramento de instrução

Erros de terminação de instrução podem ser gerados por ThrowTerminatingError()erros de mecanismo, exceções de método .NET ou -ErrorAction Stop em contextos avançados.

Attribute Descrição
Âmbito do impacto A instrução atual é interrompida; o script continua
Capturado por catch Sim
Capturado por trap Sim
Adicionado a $Error Sim
Define $? como $false Sim
Afetado por -ErrorAction Não (Break somente)
Afetado por $ErrorActionPreference Sim (pode suprimir)

Erro de encerramento de script

Erros de encerramento de script podem ser gerados por throw, erros de análise ou -ErrorAction Stop em contextos não avançados.

Attribute Descrição
Âmbito do impacto Desenrolamentos da pilha de chamadas
Capturado por catch Sim
Capturado por trap Sim
Adicionado a $Error Sim
Define $? como $false Sim
Afetado por -ErrorAction No
Afetado por $ErrorActionPreference throw: Sim (pode suprimir)
Afetado por $ErrorActionPreference Escalonado: depende do contexto

Consulte também