Kontrola błędów

Yii dostarcza kompletnego frameworku do zarządzania błędami, bazującego na mechanizmie wyjątków w PHP5. Podczas tworzenia aplikacji przeznaczonej do przetwarzania przychodzących żądań użytkownika rejestrowana jest jej metoda handleException, która przechwytuje błędy i ostrzeżenia PHP. Rejestruje ona również swoją metodę handleException aby przechwytywać niezłapane wyjątki PHP. W konsekwencji, jeśli wystąpi ostrzeżenie/uwaga lub nieprzechwycony wyjątek jeden z tych kontrolerów błędów przejmie kontrolę i rozpocznie odpowiednią procedurę kontroli błędów.

Wskazówka: Rejestracja kontrolerów błędów następuje w konstruktorze aplikacji poprzez wywołanie funkcji PHP set_exception_handler oraz set_error_handler. Jeśli nie chcesz by Yii zarządzało błędami i wyjątkami, musisz zdefiniować zmienną YII_ENABLE_ERROR_HANDLER oraz YII_ENABLE_EXCEPTION_HANDLER i przypisać jej wartość false w skrypcie wejściowym.

Domyślnie, handleError (lub handleException) wywoła zdarzenie onError (lub onException). Jeśli błąd (lub wyjątek) nie zostanie przechwycony przez żaden kontroler błędów to wezwie na pomoc komponent aplikacji errorHandler.

1. Zgłaszanie wyjątków

Zgłaszanie wyjątków w Yii nie różni się niczym od zgłaszania zwykłych wyjątków w PHP. Można użyć następującej składni aby zgłosić wyjątek, gdy nastąpi taka potrzeba:

throw new ExceptionClass('ExceptionMessage');

Yii definiuje trzy klasy wyjątków: CException, CDbException oraz CHttpException. CException jest ogólną klasą wyjątków. CDbException reprezentuje wyjątek powodowany przez pewne operacje związane z bazą danych. CHttpException reprezentuje wyjątek, który powinien być wyświetlony użytkownikowi końcowemu. Przenosi on również właściwość statusCode reprezentującą kod statusu w HTTP. Klasa wyjątku określa jak powinien być on wyświetlony, co wyjaśnimy w dalszej części.

Wskazówka: Zgłaszanie wyjątku CHttpException jest prostym sposobem raportowanie błędów zawinionych przez niepoprawne operacje wykonane przez użytkownika. Na przykład, jeśli użytkownik użyje nieprawidłowego ID postu w adresie URL, możemy zrobić co następuje aby pokazać błąd 404 (nie znaleziono strony).

// jeśli ID posta nie jest poprawne 
throw new CHttpException(404,'Nie można znaleźć podanego postu.');

2. Wyświetlanie błędów

Gdy błąd jest przekazywany do komponentu aplikacji CErrorHandler, to wybierany jest odpowiedni widok w celu wyświetlenia błędu. Jeśli błąd jest przewidziany
do wyświetlenia użytkownikowi końcowemu, tak jak CHttpException użyje on widoku nazwanego errorXXX, gdzie XXX oznacza kod statusu HTTP (np. 400, 404, 500). Jeśli błąd jest błędem wewnętrznym i powinien być pokazany jedynie
deweloperowi, użyje widoku nazwanego exception. W ostatnim przypadku, kompletny stos wywołań, jak również linia wystąpienia błędu zostaną wyświetlone.

Info: Gdy aplikacja jest uruchomiona w trybie produkcyjnym, wszystkie błędy, włączając w to wewnętrzne będą wyświetlone przy użyciu widoku errorXXX. Dzieje się tak, ponieważ stos wywołań może zawierać ważne informacje.
W tym przypadku deweloperzy powinni polegać na logu błędów aby odnaleźć prawdziwą przyczynę błędu.

CErrorHandler szuka pliku odpowiedniego pliku widoku w następującym porządku:

  1. WebRoot/themes/ThemeName/views/system: system jest to systemowy folder widoków dla aktualnie aktywnego tematu.

  2. WebRoot/protected/views/system: system jest domyślnym folderem widoków systemowych dla aplikacji.

  3. yii/framework/views: jest to standardowy folder systemowy dostarczony wraz z frameworkiem Yii.

Dlatego też, jeśli chcemy dostosować do własnych potrzeb wyświetlanie błędów, możemy po prostu utworzyć plik widoku w folderze systemowym aplikacji lub tematu. Każdy plik widoku jest zwykłym skryptem PHP zawierającym głównie kod HTML. Aby uzyskać więcej szczegółów, zobacz domyślne pliki widoków w folderze view frameworku.

3. Obsługa błędów przy użyciu akcji

Yii umożliwia używanie akcji kontrolera do obsługi wyświetlania błędu. Aby to uzyskać, powinniśmy skonfigurować obsługę błędu w konfiguracji aplikacji w następujący sposób:

return array(
  ......
  'components'=>array(
    'errorHandler'=>array(
      'errorAction'=>'site/error',
    ),
  ),
);

Powyżej, skonfigurowaliśmy właściwość CErrorHandler::errorAction tak aby wskazywała na site/error, referując do akcji error w kontrolerze SiteController. Możemy użyć innej ścieżki jeśli mamy taką potrzebę.

Możemy napisać akcję error w następujący sposób:

public function actionError()
{
  if($error=Yii::app()->errorHandler->error)
    $this->render('error', $error);
}

W akcji tej, najpierw otrzymujemy szczegółową informację o błędzie w CErrorHandler::error. Jeśli nie jest ona pusta, generujemy widok error wraz z informacją o błędzie. Informacje o błędzie zwrócone w CErrorHandler::error są tablicą zawierającą następujące pola:

  • code: kod statusu HTTP(np. 403, 500);
  • type: typ błędu (np. CHttpException, PHP Error);
  • message: wiadomość z opisem błędu;
  • file: nazwa pliku skryptu PHP, w której wystąpił błąd;
  • line: numer linie w kodzie, w której wystąpił błąd;
  • trace: stos wywołań błędu;
  • source: kontekst źródła kodu w którym wystąpił błąd.

Wskazówka: Powodem dla którego sprawdzamy czy CErrorHandler::error czy jest pusty czy też nie jest fakt iż akcja error może być bezpośrednio wywołana przez użytkownika końcowego w przypadku gdy nie ma błędu. Ponieważ przekazujemy tablicę $error do widoku, będzie ona automatycznie rozwinięta w indywidualne zmienne. W rezultacie, w widoku możemy bezpośrednio odwołać się do zmiennych takich jak $code, $type.

4. Logowanie komunikatów

Komunikat o poziomie błędu będzie zawsze logowane jeśli wystąpi błąd. Jeśli jest to błąd spowodowany przez ostrzeżenie lub wiadomość PHP, komunikat będzie zalogowany przy użyciu kategorii php; jeśli błąd spowodowany jest przez nieprzechwycony wyjątek kategorią będzie exception.ExceptionClassName (dla CHttpException jego kod statusu będzie również dołączony do kategorii). Można więc wykorzystać tą funkcjonalność logowania do monitorowania błędów powstałych podczas działania aplikacji.

$Id: topics.error.txt 3374 2011-08-05 23:01:19Z alexander.makarow $

Be the first person to leave a comment

Please to leave your comment.