Partilhar via


about_Try_Catch_Finally

Breve descrição

Descreve como usar os blocos try, catche finally para manipular erros de encerramento.

Descrição longa

Use try, catche finally blocos para responder ou manipular erros de terminação em scripts. A instrução trap também pode ser usada para lidar com erros de terminação em scripts. Para obter mais informações, consulte about_Trap.

Um erro de encerramento interrompe a execução de uma instrução. Se o PowerShell não manipular um erro de encerramento de alguma forma, o PowerShell também interromperá a execução da função ou do script usando o pipeline atual. Em outras linguagens, como C#, os erros de terminação são chamados de exceções.

Use o bloco try para definir uma seção de um script na qual você deseja que o PowerShell monitore erros. Quando ocorre um erro dentro do bloco try, o erro é primeiro salvo na variável automática $Error. Em seguida, o PowerShell procura um bloco catch para lidar com o erro. Se a instrução try não tiver um bloco de catch correspondente, o PowerShell continuará a procurar um bloco de catch apropriado ou uma instrução trap nos escopos pai. Depois que um bloco de catch for concluído ou se nenhuma instrução catch ou bloco de trap apropriada for encontrada, o bloco finally será executado. Se o erro não puder ser tratado, o erro será gravado no fluxo de erros.

Um bloco catch pode incluir comandos para rastrear o erro ou para recuperar o fluxo esperado do script. Um bloco catch pode especificar quais tipos de erro ele deteta. Uma instrução try pode incluir vários blocos de catch para diferentes tipos de erros.

Um bloco finally pode ser usado para liberar quaisquer recursos que não são mais necessários para o seu script.

try, catche finally se assemelham às palavras-chave try, catche finally usadas na linguagem de programação C#.

Sintaxe

Uma instrução try contém um bloco try, zero ou mais blocos catch e zero ou um bloco finally. Uma instrução try deve ter pelo menos um bloco catch ou um bloco finally.

A seguir mostra a sintaxe do bloco try:

try {<statement list>}

A palavra-chave try é seguida por uma lista de instruções em chaves. Se ocorrer um erro de encerramento enquanto as instruções na lista de instruções estão sendo executadas, o script passa o objeto de erro do bloco try para um bloco catch apropriado.

A seguir mostra a sintaxe do bloco catch:

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

Os tipos de erro aparecem entre parênteses. Os parênteses mais externos indicam que o elemento é opcional.

A palavra-chave catch é seguida por uma lista opcional de especificações de tipo de erro e uma lista de instruções. Se ocorrer um erro de encerramento no bloco try, o PowerShell procurará um bloco catch apropriado. Se uma for encontrada, as instruções no bloco catch são executadas.

O bloco catch pode especificar um ou mais tipos de erro. Um tipo de erro é uma exceção do Microsoft .NET Framework ou uma exceção derivada de uma exceção do .NET Framework. Um bloco catch manipula erros da classe de exceção especificada do .NET Framework ou de qualquer classe que deriva da classe especificada.

Se um bloco catch especificar um tipo de erro, esse bloco de catch manipulará esse tipo de erro. Se um bloco catch não especificar um tipo de erro, esse bloco catch manipulará qualquer erro encontrado no bloco try. Uma instrução try pode incluir vários blocos catch para os diferentes tipos de erro especificados.

A seguir mostra a sintaxe do bloco finally:

finally {<statement list>}

A palavra-chave finally é seguida por uma lista de instruções que é executada sempre que o script é executado, mesmo que a instrução try tenha sido executada sem erro ou um erro tenha sido detetado em uma instrução catch.

Observe que pressionar CTRL+C interrompe o pipeline. Os objetos enviados para o pipeline não serão exibidos como saída. Portanto, se você incluir uma instrução a ser exibida, como "Finalmente o bloco foi executado", ela não será exibida depois que você pressionar CTRL+C, mesmo que o finally bloco seja executado.

Erros de captura

O script de exemplo a seguir mostra um bloco try com um bloco catch:

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

A palavra-chave catch deve seguir imediatamente o bloco try ou outro bloco catch.

O PowerShell não reconhece "NonsenseString" como um cmdlet ou outro item. A execução desse script retorna o seguinte resultado:

An error occurred.

Quando o script encontra "NonsenseString", ele causa um erro de encerramento. O bloco catch manipula o erro executando a lista de instruções dentro do bloco .

UTILIZAÇÃO DE DECLARAÇÕES DE CAPTURA MÚLTIPLAS

Uma instrução try pode ter qualquer número de catch blocos. Por exemplo, o script a seguir tem um bloco try que baixa MyDoc.doce contém dois blocos catch:

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."
}

O primeiro bloco de catch manipula erros dos de System.Net.WebException e tipos de System.IO.IOException. O segundo bloco catch não especifica um tipo de erro. O segundo bloco catch lida com quaisquer outros erros de terminação que ocorram.

O PowerShell corresponde aos tipos de erro por herança. Um bloco catch manipula erros da classe de exceção especificada do .NET Framework ou de qualquer classe que deriva da classe especificada. O exemplo a seguir contém um bloco catch que captura um erro "Command Not Found":

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

O tipo de erro especificado, CommandNotFoundException, herda do tipo de System.SystemException. O exemplo a seguir também deteta um erro Command Not Found:

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

Este bloco de catch manipula o erro "Command Not Found" e outros erros que herdam do tipo de SystemException.

Se você especificar uma classe de erro e uma de suas classes derivadas, coloque o bloco catch para a classe derivada antes do bloco catch para a classe geral.

Observação

O PowerShell encapsula todas as exceções em um tipo de RuntimeException. Portanto, especificar o tipo de erro System.Management.Automation.RuntimeException se comporta da mesma forma que um bloco catch não qualificado.

Usando armadilhas em uma tentativa de captura

Quando ocorre um erro de encerramento em um bloco try com um trap definido dentro do bloco try, mesmo que haja um bloco de catch correspondente, a instrução trap assume o controle.

Se existir um trap em um bloco mais alto do que o trye não houver nenhum bloco de catch correspondente dentro do escopo atual, o trap assumirá o controle, mesmo que qualquer escopo pai tenha um bloco de catch correspondente.

Acesso a informações de exceção

Dentro de um catch bloco, o erro atual pode ser acedido usando a $_ variável automática.$PSItem O objeto é do tipo ErrorRecord.

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

A execução desse script retorna o seguinte resultado:

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.

Há propriedades adicionais que podem ser acessadas, como ScriptStackTrace, Exceptione ErrorDetails. Por exemplo, se alterarmos o script para o seguinte:

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

O resultado será semelhante a:

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

Libertar recursos utilizando finalmente

Para liberar recursos usados por um script, adicione um bloco finally após os blocos try e catch. As instruções de bloco finally são executadas independentemente de o bloco try encontrar um erro de encerramento. O PowerShell executa o bloco finally antes que o script seja encerrado ou antes que o bloco atual saia do escopo.

Um bloco finally é executado mesmo se você usar CTRL+C para parar o script. Um bloco finally também é executado se uma palavra-chave exit parar o script de dentro de um bloco catch.

No exemplo a seguir, o bloco try tenta baixar um arquivo para a pasta C:\temp. Os blocos catch manipulam erros que ocorrem durante o download. O bloco finally elimina o objeto WebClient e remove o arquivo temporário, se ele existir.

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 $tempPath) { Remove-Item $tempFile }
}

Consulte também