Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Wyjatki, Error Handler, Debugger
Vomit
post
Post #1





Grupa: Zarejestrowani
Postów: 122
Pomógł: 0
Dołączył: 23.01.2006

Ostrzeżenie: (0%)
-----


Witam,

Niedawno, w momencie gdy Bastion, dał do oceny swojego Debuggera, zaczałem zastanawiac sie jaki to ma sens. Mamy przeciez juz Error Handler, gdy dorzucimy do tego Wyjatki wydaje mi sie, ze to wszystko czego potrzeba.

W moim odczuciu, Error Handler, czyli standardowa obsługa bledów, moze byc jeszcze uzbrojona w dodawanie odpowiedniego wpisu do bazy i wysylanie maila do administratora. Mamy funkcje, set_error_handler, dzieki ktorej mozemy zrobic własny, "ładny", dzieki ktoremu mozemy wlasnie dodac wspomniane przeze mnie wyzej rzeczy i zmienic sposob wyswietlania bledu (tak jakby szablon) i wydaje mi sie ze to wszystko.
Ponadto mamy funkcje error_log, ktora zapisze do logow apacha te bledy.
Jest jeszcze trigger_error(), ktora w momencie istnienia wyjatkow troszke traci sens?

Wyjatki... w moim rozumieniu, przydatne przy takich sytuacjach:
  1. <?php
  2. try
  3. {
  4. $q = mysql_query();
  5. if ( !$q ) { throw new Exception('nie udalo sie zapytanie'); }
  6. }
  7. catch(Exception $e )
  8. {
  9. echo $e->__toString();
  10. }
  11. ?>

Obsługuja reszte bledów, ktore wynikna w momencie złego działania skryptu. Takze, mozemy dodac do tego "ładniejsze" wyswietlanie informacji o wyjatku, zapisywanie wyjatkow do bazy i powiadomienie mailem do admina. Mamy takze set_exception_handler, ktorej funkcji istnienia do konca nie rozumiem.

W manualu widziałem ciekawe połaczenie Error Handlera i wyjatkow (ktore sa przeciez zwyklym rozszerzeniem EH).
  1. <?php
  2.  
  3. function handler($errno, $errstr, $errfile, $errline)
  4. {
  5.  print "Error handled!\n";
  6.  throw new Exception($errstr, $errno);
  7. }
  8.  
  9. set_error_handler('handler');
  10.  
  11. try
  12. {
  13.  print 2 / 0; // simple error - division by zero
  14.  print "This will never be printed";
  15. }
  16. catch (Exception $e)
  17. {
  18.  print "Exception catched:\n";
  19.  print "Code: ".$e->getCode()."\n";
  20.  print "Message: ".$e->getMessage()."\n";
  21.  print "Line: ".$e->getLine();
  22. }
  23.  
  24. ?>


Wyjatki obsłuza zarowno typowe wyjatki jak i Error Handlera. Jesli jest to Wyjatek mozemy go zapisac do bazy i wyslac maila, jesli jest to Error, mozemy dodatkowo zapisac go do logow.

Nie widze w takim wypadku sensu istnienia Debuggera, chyba ze ma on jeszcze jakies inne zadania. Jesli sie myle prosze o wyjasnienie...
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 16)
Prph
post
Post #2





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Cytat(Vomit @ 2006-03-12 10:58:01)
catch(Exception $e )
{
    echo $e->__toString();
}

Po do wywyływać __toString()?
Przecież po to istnieje przeciążenie __toString(), żeby drukować klasy jak inne zmienne. Taki sam znakomity rezultat da:

  1. <?php
  2.  
  3.  
  4. $oException = new MyException;
  5. echo $oException;
  6.  
  7.  
  8. ?>


Oczywiście zakładamy, że klasa MyException ma przeciążoną metodę __toSrting().

Ale to tak na marginesie winksmiley.jpg
Pozdrawiam.

Ten post edytował Prph 12.03.2006, 17:41:11
Go to the top of the page
+Quote Post
hawk
post
Post #3





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

Ostrzeżenie: (0%)
-----


Cytat(Vomit @ 2006-03-12 11:58:01)
Nie widze w takim wypadku sensu istnienia Debuggera, chyba ze ma on jeszcze jakies inne zadania. Jesli sie myle prosze o wyjasnienie...

Tak naprawdę nie jest to debugger, tylko error handler, chociaż ja wolę słowo logger.

Generalnie zastosowania są dwa:
1. Podczas tworzenia aplikacji dobrze jest podpiąć coś, co wyświetli nam wyczerpujące informacje w przypadku wystąpienia błędu. A zatem narzędzie dla developera.

2. W działającej aplikacji powinno się wyświetlać krótki komunikat w przypadku błędu (a więc set_error_handler i set_exception_handler), a szczegółówe informacje gdzieś zrzucić, na ogół do pliku. Znowu potrzebny jest logger.
Go to the top of the page
+Quote Post
Vomit
post
Post #4





Grupa: Zarejestrowani
Postów: 122
Pomógł: 0
Dołączył: 23.01.2006

Ostrzeżenie: (0%)
-----


@hawk: co natomiast sadzisz o samym rozwiazaniu polaczenia Error Handlera / Loggera winksmiley.jpg z Wyjatkami:

  1. <?php
  2.  
  3. function handler($errno, $errstr, $errfile, $errline)
  4. {
  5.  print "Error handled!\n";
  6.  throw new Exception($errstr, $errno);
  7. }
  8.  
  9. set_error_handler('handler');
  10.  
  11. try
  12. {
  13.  print 2 / 0; // simple error - division by zero
  14.  print "This will never be printed";
  15. }
  16. catch (Exception $e)
  17. {
  18.  print "Exception catched:\n";
  19.  print "Code: ".$e->getCode()."\n";
  20.  print "Message: ".$e->getMessage()."\n";
  21.  print "Line: ".$e->getLine();
  22. }
  23.  
  24. ?>


W ogole zauwazyłem, ze wielu programistow tworzy u siebie kilka klas obslugujacych wyjatki. Przyklad wyciagniety z kodu hwao, z hwao's repository:

  1. <?php
  2. class SocketUnknownProtocolException extends Exception {}
  3. class SocketCantConnectException extends Exception {} 
  4. ?>


Po co tworzyc kilka klas obsługujacych wyjatki?
Go to the top of the page
+Quote Post
matid
post
Post #5





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

Ostrzeżenie: (0%)
-----


Cytat(Vomit @ 2006-03-12 20:32:46)
Po co tworzyc kilka klas obsługujacych wyjatki?

Aby móc na różny sposób lub w różnych miejscach obsługiwać różne typy wyjątków.
Go to the top of the page
+Quote Post
Vomit
post
Post #6





Grupa: Zarejestrowani
Postów: 122
Pomógł: 0
Dołączył: 23.01.2006

Ostrzeżenie: (0%)
-----


Zdefiniuj mi "rozne typy wyjatków" smile.gif
W tym konkretnym przypadku (ktory podałem) jedna klasa jest identyczna jak druga, rozni sie jedynie nazwa... a czy tu chodzi o nazwy? Wg. mnie moglaby byc to jedna klasa, ktora obsłuzyłaby nie tylko wyjatki ale takze i bledy.
Go to the top of the page
+Quote Post
bela
post
Post #7


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

Ostrzeżenie: (0%)
-----


Cytat
SocketCantConnectException

Jak piszecie po angielsku, to chociaz starajcie sie poprawnie :]


--------------------
Go to the top of the page
+Quote Post
hawk
post
Post #8





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

Ostrzeżenie: (0%)
-----


Cytat(Vomit @ 2006-03-12 21:39:56)
Zdefiniuj mi "rozne typy wyjatków" smile.gif
W tym konkretnym przypadku (ktory podałem) jedna klasa jest identyczna jak druga, rozni sie jedynie nazwa... a czy tu chodzi o nazwy? Wg. mnie moglaby byc to jedna klasa, ktora obsłuzyłaby nie tylko wyjatki ale takze i bledy.

Ale wyjątków normalnie nie obsługuje się w sposób, który podałeś. Łapiesz na top-level Exception i wywalasz na ekran. A przecież normalnie robi się catch po fragmencie kodu, łapie określony wyjątek i obsługuje. Jak chchcesz to zrobić dysponując tylko jedną klasą wyjątku? Nie będziesz wiedział, co się stało i nie będziesz w stanie nic zrobić poza wywaleniem komunikatu na ekran i przerwaniem skryptu.

Generalnie jestem przeciwny podanemu przez ciebie kodowi. Czemu ma on służyć? Wyjątki nie służą do wywalania komunikatów na ekran. Nie służą też do logowania błędów. Ani do debugowania aplikacji. Służą do obsługi błędów, a łapiąc zwykły Exception cieżko cokolwiek obsłużyć, chyba że będziemy wstawiać try/catch co drugą linię kodu.
Go to the top of the page
+Quote Post
Vomit
post
Post #9





Grupa: Zarejestrowani
Postów: 122
Pomógł: 0
Dołączył: 23.01.2006

Ostrzeżenie: (0%)
-----


Cytat(hawk @ 2006-03-13 08:46:14)
Wyjątki nie służą do wywalania komunikatów na ekran. Nie służą też do logowania błędów. Ani do debugowania aplikacji. Służą do obsługi błędów

Troszeczke mnie zbiłes z tropu.

Nie wiedziałem, ze wyjatki łapie sie "po trochu" i nie wkłada sie całego kodu w blok try{

Ale czym wiec jest ta obsługa wyjatkow?
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #10





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


"Tradycyjnie"
  1. <?php
  2. function addData( $file, &$errorStr )
  3. {
  4. if( $conn = mysql_connect( ... ) )
  5. {
  6. if ( mysql_select_db(...) )
  7. {
  8. if ( $data = file_get_contents( $file ) )
  9. {
  10. if ( mysql_query( "INSERT INTO table (some_data) VALUES( '" . $data . "' )" ) )
  11. {
  12. // OK 
  13. return TRUE;
  14. }
  15. else
  16. {
  17. $errorStr = 'zapytanie sie nie powiodlo';
  18. return FALSE;
  19. }
  20. }
  21. else
  22. {
  23.  $errorStr = 'nie mozna bylo wczytac danych';
  24. return FALSE;
  25. }
  26. }
  27. else
  28. {
  29.  $errorStr = 'nie mozna bylo wybrac bazy';
  30. return FALSE;
  31. }
  32.  
  33. }
  34. else
  35. {
  36.  $errorStr = 'nie mozna polaczyc z baza';
  37. return FALSE;
  38. }
  39. }
  40.  
  41.  
  42. $errorStr = '';
  43. if ( addData( 'jakisPlik.dat', $errStr ) )
  44. {
  45. echo "dodalo sie";
  46. }
  47. else
  48. {
  49. echo "nie dodalo sie, bo" . $errStr;
  50. }
  51. ?>


Z wyjatkami (gdyby funkcje same wyrzucaly wyjatki (jak w PDO), ehh)
  1. <?php
  2. function addData( $file )
  3. {
  4. if( $conn = mysql_connect( ... ) === FALSE )
  5. {
  6. throw new DB_Exception( mysql_error());
  7. }
  8.  
  9. if ( mysql_select_db(...) === FALSE)
  10. {
  11. throw new DB_Exception( mysql_error());
  12. }
  13.  
  14. if ( $data = file_get_contents( $file ) === FALSE )
  15. {
  16. throw new File_EXception( ...);
  17. }
  18.  
  19. if ( mysql_query( "INSERT INTO table (some_data) VALUES( '" . $data . "' )" ) === FALSE )
  20. {
  21. throw new DB_Exception( mysql_error());
  22. }
  23. }
  24.  
  25. try
  26. {
  27. addData( 'jakisPlik.dat' );
  28. echo "dodalo sie"
  29. }
  30. catch ( FileExc. $e1 )
  31. {
  32. echo "Nie dodalo sie bo: " . $e->getMessage();
  33. }
  34. catch ( DB_Exc. $e2 )
  35. {
  36. echo "Nie dodalo sie bo: " . $e->getMessage();
  37. }
  38. ?>


Cos w tym stylu, kod oczywiscie nie dziala biggrin.gif
Co wyglada na prostsze? Co jest prostsze, czytelniejsze?


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
sobstel
post
Post #11





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Cytat(Vomit)
Mamy takze set_exception_handler, ktorej funkcji istnienia do konca nie rozumiem.


a co do set_exception_handler() to warto skorzystac z tej funkcji, aby zaprogramowac obsluge wyjatkow, o ktorych zapomnimy - nie jest znowu o to tak trudno - tak na wszelki wypadek.


--------------------
"If debugging is the process of removing bugs, then programming must be the process of putting them in..."
sobstel.org
Go to the top of the page
+Quote Post
bigZbig
post
Post #12





Grupa: Zarejestrowani
Postów: 740
Pomógł: 15
Dołączył: 23.08.2004
Skąd: Poznań

Ostrzeżenie: (0%)
-----


@Vomit - nie utozsamiaj wyjatku z bledem. Ty rozumujesz tak. Jesli aplikacja rzuci wyjatek to znaczy ze cos poszlo nie tak. Twoja reakcja na wyjatke ogranicza sie jedynie do zatrzymania aplikacji i wyswietlenie tresi wyjatku na ekranie. Tymczasem przechwycenie wyjatku w stosownym momencie umozliwia podjecie innej alternatywnej akcji, ktora zrealizuje to samo zadanie ale w inny sposob, pominie dana akcje lub w ostatecznosci poinformuje o nie moznosci wykonania danego zadania.

Przyklad

Chcesz pobrac prognoze pogody ktora pobierasz z danego serwisu. Dostajesz wyjatek ze nie mozna polaczyc sie z okreslonym serwisem. Obslugujesz ten wyjatek w ten sposob ze probujesz pobrac prognoze pogody z alternatywnego serwisu. Po pobraniu danych prezentujesz je. Gdybys przechwytywal wyjatek na koncu, juz po probie wyswietlenia danych nie moglbys podjac czynnosci alternatywnych.

Moglbys tez przechwycony wyjatek przekazac dalej i na samym koncu oprocz prezentacji pogody pobranej z alternatywnego serwisu wyswietlibys tez komunikat o niepowodzeniu pobrania informacji z pierwotnego serwisu.

Ten post edytował bigZbig 15.03.2006, 10:26:29


--------------------
bigZbig (Zbigniew Heintze) | blog.heintze.pl
Go to the top of the page
+Quote Post
aleksander
post
Post #13





Grupa: Przyjaciele php.pl
Postów: 742
Pomógł: 0
Dołączył: 14.12.2003
Skąd: Gdańsk, Trójmiasto

Ostrzeżenie: (0%)
-----


Cytat(sopel @ 2006-03-15 10:08:30)
Cytat(Vomit)
Mamy takze set_exception_handler, ktorej funkcji istnienia do konca nie rozumiem.


a co do set_exception_handler() to warto skorzystac z tej funkcji, aby zaprogramowac obsluge wyjatkow, o ktorych zapomnimy - nie jest znowu o to tak trudno - tak na wszelki wypadek.

a moim zdaniem lepiej wszystkie wyjątki wyłapywac "na samej górze". Np w moim frameworku wyglada to tak:
  1. <?php
  2. try{
  3. $oFC = new FrontController( simplexml_load_file( 'exampleconfig.xml' ) );
  4. } catch( Exception $oException ) {
  5. echo $oException;
  6. }
  7. ?>
oczywiscie catchy moze byc wiecej ale ogolnie chodzi o to aby wyłapywc wyjątki w jednym miejscu poniewaz jest to czytelniejsze, chyba ze napisalismy plugin do programu i ma on niestandardową obsługę wyjątków. no i nie trzeba sie bawic w set_exception_handler ktore ani ladnie nie wyglada ani nie jest "standardowe" bo np w javie czegos takiego nie ma. Nauczcie sie pisac czysty kod:)

A zeby nie zapomniec o jakis wyjatkach jako ostatni catch dajemy Exception ktory wylapie kazdy wyjatek.
Go to the top of the page
+Quote Post
Vomit
post
Post #14





Grupa: Zarejestrowani
Postów: 122
Pomógł: 0
Dołączył: 23.01.2006

Ostrzeżenie: (0%)
-----


bigZbig: wyjasniłes mi sporo dzieki temu przykladowi.

Nadal jednak nie rozumiem jaka bedzie roznica jak wszystkie wyjatki bede wylapywal za pomoca jednej klasy nazwanej MyException. hawk napisał, ze wtedy nie bede wiedział co sie dokładnie stało, a wg. mnie bede wiedzial, bo po to jest komunikat.
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #15





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Cytat
wyjatki bede wylapywal za pomoca jednej klasy nazwanej MyException.

Wyjatku nie lapiesz obiektem *Exception.
Wyjatek jest obiektem, instancja jakiejs klasy pochodnej-od/lub Exception.
Jak bedziesz sprawdzal czy wystapil wyjatek na poziomie bazy danych czy np. z pododu bledu odczytu pliku:

  1. <?php
  2. catch ( MyException $e )
  3. {
  4. switch( $e->getMessage )
  5. {
  6. case 'Wystapil blad przy zapytanie: SELECT * FROM....':
  7. case 'Wystapil blad .....':
  8. case 'Wystapil blad .....':
  9. case 'Wystapil blad .....':
  10. case 'Wystapil blad .....':
  11. case 'Wystapil blad .....':
  12. case 'Wystapil blad przy laczeniu sie z baza danych':
  13. // a co jak sie walnales i wpisales message: 'Wystapil bald przy laczeniu sie z baza danych': questionmark.gif?
  14. {
  15. // tutaj obsluga bazy danych
  16. }
  17. case 'Plik nie istnieje: 'aaa-inc.php':
  18. case 'Plik jest uszkodzony:
  19. case 'Plik jest zalockowany':
  20. case 'Plik .......':
  21. case 'Brak uprawnien do zapisu do pliku':
  22. // a co gdy w new MyException( msg ) podales msg jako 'Brak uprawnień do zapisu do pliku'; questionmark.gif?
  23. }
  24. }
  25. ?>

a teraz normalnie
  1. <?php
  2.  
  3. catch ( SQLException $e )
  4. {
  5.  // obsluga wyjatkow z bazy danych, np. wyrzucamy kolejny wyjatek i lapiemy go gdzi
    es indziej:
  6.  throw new ApplicationException( 'Blad w aplikacji -- nie mozna kontynuowac' );
  7.  
  8. }
  9. catch ( FileException $e )
  10. {
  11.  // obsluga wyjatkow z plikow
  12. }
  13. catch ( Exception $e )
  14. {
  15.  // obsluga pozostalych wyjatkow
  16. }
  17.  
  18. ?>



Chodzi o to zeby KOD php wiedzial co sie stalo (na podst. klasy wyjatku) a nie zeby user wiedzial (na podstawie tresci komunikatu wyjatku)


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
bigZbig
post
Post #16





Grupa: Zarejestrowani
Postów: 740
Pomógł: 15
Dołączył: 23.08.2004
Skąd: Poznań

Ostrzeżenie: (0%)
-----


@Vomit - jesli wszystkie decyzje po wystapieniu wyjatku beda zalezaly od Ciebie to faktycznie mozesz stosowac tylko jeden ich rodzaj. Jak juz wczesniej napisalem wyjatki mozna zastosowac do sterowania praca aplikacji (przyklad z prognoza pogody) ale aplikacja przecierz nie przeczyta tresci komunikatu. Jedyne czym sie moze pokierowac to rodzajem przechwyconego wyjatku. Ty nadal sprowadzasz wyjatek do komunikatu bledu, a przeciez rzuceniu wyjatku nie musi towarzyszyc wyswietlenie komunikatu.


--------------------
bigZbig (Zbigniew Heintze) | blog.heintze.pl
Go to the top of the page
+Quote Post
Termit_
post
Post #17





Grupa: Zarejestrowani
Postów: 44
Pomógł: 0
Dołączył: 11.06.2005
Skąd: Gostyń

Ostrzeżenie: (0%)
-----


Poza tym wartość zmiennej Exception::$message może ulec zmianie, a wówczas należałoby to zmienić w każdym miejscu. No i - jeszcze pozostaje kwestia i18n... tak, stosowanie kilku klas dziedziczących po Exception jest IMHO dobrym rozwiązaniem.


--------------------
@nospor: trzymajcie się. Wszystko będzie dobrze!
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 03:28