ErrorAction e preferências
Esta aula aborda como controlar o tratamento de erros no PowerShell usando o parâmetro -ErrorAction, a variável de preferência $ErrorActionPreference e o parâmetro -ErrorVariable, com boas práticas para escrever scripts robustos.
No PowerShell, erros são inevitáveis, mas a forma como você os trata pode determinar a robustez dos seus scripts. Nesta aula, exploraremos três mecanismos fundamentais para gerenciar erros: o parâmetro -ErrorAction (presente em cmdlets avançados), a variável de preferência $ErrorActionPreference (que define o comportamento padrão) e o parâmetro -ErrorVariable (que captura erros em uma variável). Compreender esses conceitos é essencial para escrever scripts previsíveis e resilientes.
O PowerShell classifica erros em duas categorias: terminantes (que interrompem a execução) e não terminantes (que permitem continuar). Os mecanismos desta aula atuam principalmente sobre erros não terminantes, que são os mais comuns em cmdlets como Get-ChildItem, Copy-Item ou Remove-Item.
-ErrorAction
O parâmetro -ErrorAction está disponível na maioria dos cmdlets avançados (que implementam [CmdletBinding()]). Ele permite especificar, no momento da chamada, como o cmdlet deve reagir a erros não terminantes. Os valores possíveis são:
- Continue (padrão): exibe a mensagem de erro e continua a execução.
- Stop: trata o erro como terminante, lançando uma exceção.
- SilentlyContinue: suprime a mensagem de erro e continua.
- Inquire: pergunta ao usuário o que fazer antes de cada erro.
- Ignore: (PowerShell 3.0+) não registra o erro nem interrompe; não exibe mensagem.
- Suspend: (fluxo de trabalho) suspende a execução.
Exemplo prático: suponha que você queira listar um arquivo que pode não existir, mas sem gerar mensagens de erro.
Get-Item -Path "C:\ArquivoInexistente.txt" -ErrorAction SilentlyContinue
O comando acima não exibirá erro. Se quiser que o erro interrompa o script (como uma exceção), use -ErrorAction Stop:
Get-Item -Path "C:\ArquivoInexistente.txt" -ErrorAction Stop
Isso lançará um erro terminante, que pode ser capturado com try/catch.
$ErrorActionPreference
A variável $ErrorActionPreference define o comportamento padrão para erros não terminantes em todo o escopo atual (script, função ou sessão). Ela aceita os mesmos valores que -ErrorAction, exceto Ignore (que não é suportado como preferência). O valor padrão é Continue.
Alterar essa variável afeta todos os cmdlets que não especificam explicitamente -ErrorAction. Por exemplo, para suprimir erros em todo um script:
$ErrorActionPreference = 'SilentlyContinue'
Get-Item "C:\Inexistente.txt" # Nenhum erro exibido
Get-ChildItem "C:\OutroInexistente" # Também sem erro
É uma boa prática restaurar o valor original após o uso, especialmente em scripts maiores, para não afetar outros comandos inesperadamente. Use try/finally ou salve o valor original:
$originalPref = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
try {
# comandos que devem parar no primeiro erro
} finally {
$ErrorActionPreference = $originalPref
}
Lembre-se de que $ErrorActionPreference não afeta erros de sintaxe ou erros terminantes explícitos (como throw).
-ErrorVariable
O parâmetro -ErrorVariable permite capturar os erros não terminantes gerados por um cmdlet em uma variável específica, sem interromper a execução. A variável recebe uma lista de objetos ErrorRecord. É útil para inspecionar ou registrar erros posteriormente.
Sintaxe: -ErrorVariable NomeVariavel. Use + antes do nome para adicionar em vez de substituir.
Exemplo:
$erros = @()
Get-ChildItem -Path "C:\PastaInexistente" -ErrorVariable erros -ErrorAction SilentlyContinue
if ($erros) {
Write-Host "Ocorreram $($erros.Count) erro(s):"
$erros | ForEach-Object { $_.Exception.Message }
}
No exemplo, mesmo com -ErrorAction SilentlyContinue, os erros são capturados em $erros. Você pode então analisá-los sem interromper o fluxo.
Para adicionar erros a uma variável existente (sem substituir), use +:
$todosErros = @()
Get-ChildItem "C:\Pasta1" -ErrorVariable +todosErros -ErrorAction SilentlyContinue
Get-ChildItem "C:\Pasta2" -ErrorVariable +todosErros -ErrorAction SilentlyContinue
Isso acumula erros de múltiplos comandos.
Boas práticas
Ao lidar com erros no PowerShell, siga estas recomendações:
- Prefira
-ErrorAction Stopem operações críticas para que erros sejam tratados como exceções e possam ser capturados comtry/catch. Isso torna o fluxo de erro explícito. - Use
$ErrorActionPreference = 'Stop'no início de scripts que exigem que qualquer erro interrompa a execução, mas sempre restaure a preferência original ao final (usetry/finallyou escopo local). - Evite
SilentlyContinuesem capturar erros; se você suprime erros, pelo menos registre-os em log ou use-ErrorVariablepara não perder informações de diagnóstico. - Não use
$ErrorActionPreference = 'Ignore'(não é suportado como preferência); para ignorar erros, use o parâmetro-ErrorAction Ignorediretamente no cmdlet. - Documente o comportamento esperado em scripts compartilhados: indique qual política de erro está sendo usada.
- Teste seus scripts com diferentes cenários de erro (arquivo ausente, permissão negada, etc.) para garantir que o tratamento de erros está correto.
Lembre-se: um script que lida bem com erros é mais confiável e fácil de depurar.
Referências
- about_Preference_Variables (Microsoft Docs)
- about_Try_Catch_Finally (Microsoft Docs)
- about_CommonParameters (Microsoft Docs)
- Everything About Exceptions (PowerShell Scripting)
- about_ErrorActionPreference (Microsoft Docs)
Exercícios
- Crie um comando que tente obter o item 'C:\Temp\nonexistent.txt' com
-ErrorAction Stope capture o erro em um blocotry/catch, exibindo a mensagem de erro. - Altere a preferência de erro para
SilentlyContinuee executeGet-ChildItemem uma pasta inexistente. Verifique que nenhum erro é exibido. Depois restaure a preferência. - Use o parâmetro
-ErrorVariablepara capturar erros deRemove-Itemao tentar excluir um arquivo que não existe, sem exibir o erro na tela. Depois exiba a quantidade de erros. - Escreva um script que liste o conteúdo de três pastas (C:\Folder1, C:\Folder2, C:\Folder3) e acumule todos os erros em uma única variável usando
-ErrorVariablecom+. Ao final, se houver erros, exiba a mensagem de cada um. - Explique a diferença entre
-ErrorAction Stope$ErrorActionPreference = 'Stop'e dê um exemplo onde usar um é preferível ao outro.
try {
Get-Item -Path "C:\Temp\nonexistent.txt" -ErrorAction Stop
} catch {
Write-Host "Erro capturado: $($_.Exception.Message)"
}
$original = $ErrorActionPreference
$ErrorActionPreference = 'SilentlyContinue'
Get-ChildItem -Path "C:\PastaInexistente"
$ErrorActionPreference = $original
$erros = @()
Remove-Item -Path "C:\Temp\nonexistent.txt" -ErrorVariable erros -ErrorAction SilentlyContinue
Write-Host "Quantidade de erros: $($erros.Count)"
$todosErros = @()
$pastas = @("C:\Folder1", "C:\Folder2", "C:\Folder3")
foreach ($pasta in $pastas) {
Get-ChildItem -Path $pasta -ErrorVariable +todosErros -ErrorAction SilentlyContinue
}
if ($todosErros) {
foreach ($erro in $todosErros) {
Write-Host $erro.Exception.Message
}
}
-ErrorAction Stop é aplicado a um único comando, enquanto $ErrorActionPreference = 'Stop' afeta todos os comandos no escopo atual. Use -ErrorAction Stop quando apenas um comando específico deve gerar exceção (ex.: leitura de um arquivo de configuração). Use $ErrorActionPreference = 'Stop' quando todo o script deve parar ao primeiro erro (ex.: em uma sequência de operações dependentes). Exemplo: em um script que copia arquivos e depois os processa, se qualquer cópia falhar, o processamento não deve continuar; então defina $ErrorActionPreference = 'Stop' no início.