![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 1 233 Pomógł: 87 Dołączył: 6.03.2009 Ostrzeżenie: (40%) ![]() ![]() |
Witam
Jestem w trakcie pisania biblioteki - ujednoliconego API - służącej do obsługi usług rozwiązywania captch. Nie muszę chyba nikogo przekonywać, że dobrze zaprojektowany system wyjątków to podstawa. Niestety nigdy się w to nie bawiłem, tzn. często używam wyjątków, ale nigdy nie próbowałem definiować własnych klas wyjątków. Przeczyłem ten artykuł: http://blogs.msdn.com/b/kcwalina/archive/2...ierarchies.aspx Uznałem że zaproponowany tam podział na "usage exception" oraz "system exception" wydaje się rozsądny. Moj kod wygląda następująco:
(przepraszam za tabulatory ale odzwierciedlają one hierarchę). Pytanie: Co należałoby tu zmienić, czy np. "202: insufficient funds" pasuje bardziej do "SystemLogical_Exception" czy może "Usage_Exception". Czy to co zrobiłem ma jakikolwiek sens? (IMG:style_emoticons/default/smile.gif) Ten post edytował wNogachSpisz 26.02.2013, 19:10:13 |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
1. W PHP powinieneś rozróżnić dwie podstawowe "rodziny" wyjątków: LogicalException oraz RuntimeException (hierarchia wbudowanych wyjątków). Te pierwsze wynikają z "błędów programisty", te ostatnie zaś z błędnego użycia przez użytkownik, konfiguracji środowiska i ogóle wszystkiego co możne wystąpić wyłącznie w trakcie działania aplikacji.
2. Twoje wyjątki powinny u swojej podstawy rozszerzać, którąś z tych dwóch gałęzi, nie zaś bezpośrednio klasę Exception. 3. Na dobrą sprawę w większości przypadków nie potrzebujesz nawet własnych klas dla tych wyjątków. |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 1 233 Pomógł: 87 Dołączył: 6.03.2009 Ostrzeżenie: (40%) ![]() ![]() |
1. W PHP powinieneś rozróżnić dwie podstawowe "rodziny" wyjątków: LogicalException oraz RuntimeException (hierarchia wbudowanych wyjątków). Te pierwsze wynikają z "błędów programisty", te ostatnie zaś z błędnego użycia przez użytkownik, konfiguracji środowiska i ogóle wszystkiego co możne wystąpić wyłącznie w trakcie działania aplikacji. Chyba odwrotnie, LogicalException to błąd użycia, a RuntimeException, błąd programu. Tak czy inaczej, podział ten wydaje gorszy od zaproponowanego przez P. Krzysztofa. Podam przykład: "network error" problem z siecią nie powstaje z powodu błędnego inputa, ani tego że program jest źle napisany, tylko.. no wlasnie, z przyczyn niezależnych :-] Rozumiem że według Ciebie powiniem rozszerzyc RuntimeException o NetworkException, ale takie podejście to pułapka, czytamy: „I would consider not creating new exception types till you are sure you need them. At which point, you can create a new exception type by inheriting from the currently throw type. Sometimes it might result in slightly strange exception hierarchy (for example, a custom exception inheriting from InvalidOperationException), but it’s not a big deal in comparison to the cost having unnecessary exception types in your library, which makes the library more complex, adds development cost, increases working set, etc.” Autor radzi aby nie tworzyć nowych klas, bo program staje się zbyt skomplikowany, w tym punkcie się z nim zgadzam. Błąd "network error" klasyfikuje w tym podziale jako "System Logical Exception" , czyli błąd ktory nie musi spowodować zakończenia programu i nie jest spowodowany błędnym inputem. 2. Twoje wyjątki powinny u swojej podstawy rozszerzać, którąś z tych dwóch gałęzi, nie zaś bezpośrednio klasę Exception. Przyjrzyj się dokładniej, dziedziczą z „Decaptcha_Exception”. 3. Na dobrą sprawę w większości przypadków nie potrzebujesz nawet własnych klas dla tych wyjątków. Nigdy nie potrzebowałem, ale dzisiaj uznałem że czas na małe rozwarstwienie. Warto zauważyć, że zostawiam sobie fallback, mianowicie, wszystkie wyjątki można rozpoznać bez podziału na klasy po ich unikatowych kodach błędu. Ten post edytował wNogachSpisz 26.02.2013, 19:07:48 |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat Chyba odwrotnie, LogicalException to błąd użycia, a RuntimeException, błąd programu. Nie, LogicException to błędy w samym kodzie, np.:RuntimeException to zaś wszystkie błędy, które wynikły ze względu na otrzymane z zewnątrz dane (od użytkownika, z pliku czy z sieci). Cytat Tak czy inaczej, podział ten wydaje gorszy od zaproponowanego przez P. Krzysztofa. Podam przykład: "network error" problem z siecią nie powstaje z powodu błędnego inputa, ani tego że program jest źle napisany, tylko.. no wlasnie, z przyczyn niezależnych :-] Nie zgodziłbym się. Jeżeli próbujesz skorzystać np. z socketu, który nie jest w ogóle podpięty (zbindowany) możemy mówić o LogicException - bo jako programista powinieneś go zbindować. Jeżeli zaś problem pojawił się z powodu wprowadzenia poprawnej, lecz nieistniejącej nazwy hosta, albo akurat internet nam padł jest to RuntimeException. Jeżeli jakiś błąd wynika z przyczyn niezależnych niemal zawsze będzie to RuntimeException.Cytat Nigdy nie potrzebowałem, ale dzisiaj uznałem że czas na małe rozwarstwienie. Warto zauważyć, że zostawiam sobie fallback, mianowicie, wszystkie wyjątki można rozpoznać bez podziału na klasy po ich unikatowych kodach błędu. Podobnie jak autor artykułu czy Ty sam, nie jestem zwolennikiem tworzenia dziesiątek klas dla wyjątków. Zauważ, że u Ciebie spokojnie można wykorzystać wbudowane wyjątki PHP do osbługi przynajmniej części. Resztę z nich mógłbyś zapewne obsłużyć przy pomocy dużo "płytszej" hierarchii. Hierarchia wyjątków zawsze będzie stanowiła dosyć poważny problem, ale przy raptem 13 wyjątkach jakie tutaj zaprezentowałeś odwzorowywanie hierarchii z C#/.NET nie jest dobrym pomysłem. Szczególnie, że pokrywa się częściowo z SPL-owską. |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 279 Pomógł: 60 Dołączył: 25.02.2012 Ostrzeżenie: (0%) ![]() ![]() |
W tym przykładzie z
jeszcze lepiej by było rzucić BadMethodCallException. A tak w ogóle, to hierarchia wyjątków w PHP jest dziwna, słabo wyjaśniona w manualu i nie wiadomo w zasadzie jak z niej korzystać w spójny sposób (brak zgodności w tej kwestii wśród programistów). Same opisy tych klas są momentami śmieszne - szczególnie, gdy opisują błędy czasu kompilacji i wykonania (sic!). |
|
|
![]() ![]() |
![]() |
Aktualny czas: 13.10.2025 - 15:38 |