Processamento de erros

Concluído

Até agora, você viu como adicionar parâmetros e construções de controle de fluxo pode tornar seus scripts flexíveis e mais seguros de usar. Mas, às vezes, você terá erros em seus scripts. Você precisa de uma maneira de lidar com esses erros.

Aqui estão alguns fatores a considerar:

  • Como lidar com o erro. Às vezes, você recebe erros dos quais pode se recuperar e, às vezes, é melhor parar o script. É importante pensar nos tipos de erros que podem acontecer e na melhor forma de os gerir.

  • Quão grave é o erro. Existem vários tipos de mensagens de erro. Alguns são mais como avisos para o usuário de que algo não está bem. Alguns são mais graves, e o usuário realmente precisa prestar atenção. Sua abordagem de tratamento de erros depende do tipo de erro. A abordagem pode ser qualquer coisa, desde apresentar uma mensagem até aumentar o nível de gravidade e, potencialmente, interromper o script.

Erros

Um cmdlet ou função, por exemplo, pode gerar muitos tipos de erros. Recomendamos que você escreva código para gerenciar cada tipo de erro que possa ocorrer e que você os gerencie adequadamente de acordo com o tipo. Por exemplo, digamos que você está tentando gravar em um arquivo. Você pode obter vários tipos de erros, dependendo do que está errado. Se você não tiver permissão para gravar no arquivo, poderá receber um tipo de erro. Se o arquivo não existir, você pode obter outro tipo de erro e assim por diante.

Há dois tipos de erros que você pode obter ao executar o PowerShell:

  • Erro de encerramento. Um erro desse tipo interromperá a execução na linha onde o erro ocorreu. Você pode lidar com esse tipo de erro usando um ou Try-CatchTrap. Se o erro não for tratado, o script será encerrado nesse ponto e nenhuma instrução será executada.

    Nota

    A Trap construção está fora do escopo deste módulo. Se você estiver interessado, consulte Sobre o Trap.

  • Erro de não terminação. Esse tipo de erro notificará o usuário de que algo está errado, mas o script continuará. Você pode atualizar esse tipo de erro para um erro de encerramento.

Gerenciando erros usando Try/Catch/Finally

Você pode pensar em um erro de encerramento como um erro inesperado. Estes erros são graves. Quando você lida com um, você deve considerar que tipo de erro é e o que fazer a respeito.

Há três construções relacionadas que podem ajudá-lo a gerenciar esse tipo de erro:

  • Try. Você usará um Try bloco para encapsular uma ou mais instruções. Você colocará o código que deseja executar — por exemplo, código que grava em uma fonte de dados — dentro de chaves. A Try deve ter pelo menos um Catch ou Finally bloco. Veja como fica:

    Try {
       # Statement. For example, call a command.
       # Another statement. For example, assign a variable.
    }
    
  • Catch. Você usará essa palavra-chave para detetar ou gerenciar um erro quando ele ocorrer. Em seguida, você inspecionará o objeto de exceção para entender que tipo de erro ocorreu, onde ocorreu e se o script pode ser recuperado. A Catch segue-se imediatamente após um Try. Você pode incluir mais de um Catch — um para cada tipo de erro — se desejar. Eis um exemplo:

    Try {
       # Do something with a file.
    } Catch [System.IO.IOException] {
       Write-Host "Something went wrong"
    }  Catch {
       # Catch all. It's not an IOException but something else.
    }
    

    O script tenta executar um comando que faz algum trabalho de E/S. O primeiro Catch deteta um tipo específico de erro: [System.IO.IOException]. O último Catch pega qualquer coisa que não seja um [System.IO.IOException].

  • Finally. As instruções neste bloco serão executadas independentemente de algo correr mal. Você provavelmente não usará muito esse bloco, mas ele pode ser útil para limpar recursos, por exemplo. Para usá-lo, adicione-o como o último bloco:

    Try {
       # Do something with a file.
    } Catch [System.IO.IOException] {
       Write-Host "Something went wrong"
    }  Catch {
       # Catch all. It's not an IOException but something else.
    } Finally {
       # Clean up resources.
    }
    

Erros de inspeção

Falamos sobre objetos de exceção no contexto da captura de erros. Você pode usar esses objetos para inspecionar o que deu errado e tomar as medidas apropriadas. Um objeto de exceção contém:

  • Uma mensagem. A mensagem diz-lhe em poucas palavras o que correu mal.

  • O stacktrace. O stacktrace informa quais instruções foram executadas antes do erro. Imagine que você tem uma chamada para a função A, seguida por B, seguida por C. O script para de responder em C. O stacktrace mostrará essa cadeia de chamadas.

  • A linha ofensiva. O objeto de exceção também informa qual linha o script estava sendo executado quando o erro ocorreu. Essas informações podem ajudá-lo a depurar seu código.

Então, como inspecionar um objeto de exceção? Há uma variável embutida, $_, que tem uma exception propriedade. Para obter a mensagem de erro, por exemplo, você usaria $_.exception.messageo . No código, pode ter esta aparência:

Try {
     # Do something with a file.
   } Catch [System.IO.IOException] {
     Write-Host "Something IO went wrong: $($_.exception.message)"
   }  Catch {
     Write-Host "Something else went wrong: $($_.exception.message)"
   }

Suscitar erros

Em algumas situações, você pode querer causar um erro:

  • Erros de não terminação. Para esse tipo de erro, o PowerShell apenas notifica que algo deu errado, usando o Write-Error cmdlet, por exemplo. O script continua a ser executado. Esse pode não ser o comportamento que você quer. Para aumentar a gravidade do erro, você pode usar um parâmetro como -ErrorAction causar um erro que pode ser detetado com Try/Catch, assim:

    Try {
       Get-Content './file.txt' -ErrorAction Stop
    } Catch {
       Write-Error "File can't be found"
    }
    

    Usando o -ErrorAction parâmetro e o valor Stop, você pode causar um erro que Try/Catch pode pegar.

  • Regras de negócio. Você pode ter uma situação em que o código não para de responder, mas você quer que ele por motivos comerciais. Imagine que você está limpando a entrada e verifica se um parâmetro é um caminho. Um requisito de negócios pode especificar que apenas determinados caminhos são permitidos ou que o caminho precise ter uma determinada aparência. Se as verificações falharem, faz sentido lançar um erro. Em uma situação como essa, você pode usar um Throw bloco:

    Try {
       If ($Path -eq './forbidden') 
       {
         Throw "Path not allowed"
       }
       # Carry on.
    
    } Catch {
       Write-Error "$($_.exception.message)" # Path not allowed.
    }
    
    

    Nota

    Em geral, não use Throw para validação de parâmetros. Em vez disso, use atributos de validação. Se você não conseguir fazer seu código funcionar com esses atributos, um Throw pode estar OK.