niedziela, 26 stycznia 2014

Error handling w PowerShellu

Tym razem o obsłudze błędów w PowerShell. Błędów w kodzie w PS jest bardzo dużo i jest to nieodłączny element PS :). Dlatego chciałbym Ci opisać najważniejsze kwestie związane w Error Handlingiem. Mamy 2 typy obsługi błędów - zakończające (terminating) i nie zakończające (non-terminating) działanie skryptu.
Przykład obsługi błędów zakończającego jest poniżej:
"Before"; 
throw "Error!"; 
"After"
Wtedy w konsoli mamy:
Before
Error!
At line:2 char:1
+ throw "Error!";
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Error!:String) [], RuntimeException
    + FullyQualifiedErrorId : Error!
Na ogół taki typ obsługi błędów stosuje się gdy:
- występują składniowe błędy w skrypcie
- alarmować o błędach krytycznych
- rzucanie błędów w bloku try-catch-finally (tak jest, PS też ma try-catcha)

Stosuje się blok try-catch, aby przechwycić taki błąd:
try
{
throw "Error!"; 
}
catch
{
    Write-Host "Catch"
}
Więcej o try-catch można poczytać w about_Try_Catch_Finally.


Do drugiego typ (non-terminating) obsługi błędów stosuje się komendę Write-Error, a przykład jest przedstawiony poniżej:
"Before"; 
Write-Error "Error!"; 
"After"

Na końcu komunikatu jest tekst "After":
Before
"Before"; 
Write-Error "Error!"; 
"After" : Error!
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
 
After
Typ obsługi błędów nie zakończający działanie stosuje się gdy:
- chcemy zarejestrować błąd
- błąd nie przeszkadza w dalszym działaniu skryptu
- błąd jest przy wywołaniu elementów ( metod, właściwości) na obiektach .NETowych


Oprócz tych komend, ważne są zmienne pomocnicze
- $? - Jeżeli prawda to wywołanie zakończyło się bez błędu. Jeżeli fałsz to oznacza, że był błąd lub częściowy sukces (w trakcie wywoływania)
dir | %{ $?;$_.ABc(); $?}
I na outpucie mamy:
True
Method invocation failed because [System.IO.DirectoryInfo] does not contain a method named 'ABc'.
At line:1 char:13
+ dir | %{ $?;$_.ABc(); $?}
+             ~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
 
False
True
Method invocation failed because [System.IO.DirectoryInfo] does not contain a method named 'ABc'.
At line:1 char:13
+ dir | %{ $?;$_.ABc(); $?}
+             ~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
 
False
Dla wywołanych programów konsolowych jest sprawdzany ExitCode. Jeżeli ma on wartość 0 to $? będzie przyjmował wartość true.

- $Error - jest to ArrayLista z błędami jakie wystąpiły w trakcie aktualnej sesji. Najmłodszy błąd jest dodawany na początek listy.
- $LastExitCode - Przy wywoływaniu aplikacji konsolowej, zmienna zawiera wartość ExitCode ostatniej uruchamianej aplikacji
- $MaximumErrorCount - Określa ilość trzymanych błędów w kolekcji $Error. Domyślna wartość jest 256 a maksymalna ilość zapisanych błędów może być 32 768.

- $ErrorActionPreference - Określa sposób zachowania się konsoli kiedy wystąpi błąd. Może przujmować takie wartości jak "SilentlyContinue", "Continue", "Stop", i "Inquire". Domyślna wartość to "Continue". Przykład użycia zapytania w momencie wystąpienia błędu jest przedstawiony poniżej:
$ErrorActionPreference ="inquire"
Write-Error "pop up text error"


- $ErrorView - określa sposób wyświetlenia błędów na host'ie. Domyślna wartość to "NormalView", ale w przypadku produkcyjnego środowiska można zmienić na "CategoryView", aby dostać zwięzły jednolinijkowy komunikat


Czasami przy niektórych komendach, które mogą zwrócić błąd można zastosować parametry -ErrorAction SilentlyContinue, aby komunikaty o błędach były 'przemilczane'. Jest to bardzo dobrze rozwiązanie, gdyż zmienna $ErrorActionPreference jest zmienną globalna dla wszystkich poleceń.

Następnym razem napisze coś o trapie i try-catch

Brak komentarzy:

Prześlij komentarz