Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Obsluga wyjatkow
q.michal
post 27.04.2016, 09:06:34
Post #1





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

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


Czesc,

Chcialbym oprogramowac obsluge wyjatkow w swoim FW i zastanawiam sie jak rozwiazac pewna kwestie.
Mianowiciechcialbym aby:

1) wszystkie wyjatki byly logowane, bez wzgledu na to czy zostana wyswietlone czy nie (bo wyjatek moze wystapic np podczas laczenia sie do bazy danych w trakcie instalacji i w tym wypadku wolalbym wyswietlic informacje uzytkownikowi, ze nie mozna sie podlaczyc i by sprawdzil wprowadzone dane).
2) Aby czesc wyjatkow byla poprostu wyswietlana uzytkownikowi, a czesc tylko logowana

No i tutaj pojawia sie pytanie jak to rozwiazac. Czy to ja w klasie zapewniajacej obsluge wyjatkow powinienem o to wszystko zadbac, czy moze wlasnie piszac w przyszlosci np. wspomniany instalator powinienem tam taki wyjatek zlapac i go odpowiednio obsluzyc (wyswietlic komunikat)? Tylko co wtedy z logowaniem? Jezeli w klasie implementujacej obsluge wyjatkow obsluze logowanie ich do pliku, to przy lapaniu wyjatku, exception handler nie zostanie wywolany i nie umiesci wpisu w pliku z logami. Moze logowanie wyjatkow powinno nastapic w innym miejscu (np. w tym wypadku w klasie implementujacej DBAL)?


Bede wdzieczny za wszystkie sugestie i pomysly.
Pozdrawiam.
Go to the top of the page
+Quote Post
com
post 27.04.2016, 21:54:19
Post #2





Grupa: Zarejestrowani
Postów: 3 033
Pomógł: 366
Dołączył: 24.05.2012

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


no wyjątki to powinno łapać twoje core nie?
Go to the top of the page
+Quote Post
Pyton_000
post 28.04.2016, 07:17:07
Post #3





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


A może to? http://php.net/manual/en/function.set-exception-handler.php
I tak jak @com powiedział łap je w Core.
Go to the top of the page
+Quote Post
q.michal
post 28.04.2016, 08:32:54
Post #4





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

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


No tak, w core byloby najlepiej.
Ale tak jak wspomnialem wczesniej, chcialbym osiagnac kilka rzeczy:
1) Aby wszystkie wyjatki byly rowniez logowane. Mam juz napisany kod odpowiedzialny za logowanie, wiec moge go wykorzystac w klasie Exception i przed wyswietleniem wyjatku moge go zalogowac.
2) Chcialbym rowniez aby nie kazdy wyjatek byl wyswietlany uzytkownikowi w postaci strony z bledem. Przyklad podalem juz z baza danych. Chcialbym wowczas powrocic do formularza i dac uzytkownikowi mozliwosc poprawienia bledow.
3) Jezeli poza corem przy probie nawiazania polaczenia do bazy uzyje try {} catch {}, to przechwyce wyjatek i jezeli sie nie myle, nie zostanie on wtedy zalogowany do pliku - a to logowanie ma byc obligatoryjne, bez wzgledu czy uzytkownik zostanie przekierowany spowrotem do formularza, czy tez dostanie strone z bledem, czy srypt w konsoli zakonczy swoje dzialanie, czy tez nie.
Go to the top of the page
+Quote Post
Pyton_000
post 28.04.2016, 08:50:59
Post #5





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


A zobaczyłeś link ?
Go to the top of the page
+Quote Post
q.michal
post 28.04.2016, 09:00:00
Post #6





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

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


Tak, exception handler.
I kazdy wyjatek ktory nie jest w bloku try {} catch {} bedzie przez niego obsluzony. Taki handler moze go zalogowac (np do pliku) a pozniej wyswietlic strone z bledem.
Nadal jednak nie odpowiada to na pytanie co zrobic jezeli chce zalogowac wyjatek, ale nie chce go wyswietlac uzytkownikowi?
Czy wowczas w przykladowym instalatorze powinienem uzyc try {} catch{} i jezeli zlapie jakis wyjatek to przekierowac go do formularza i wyswietlic komunikat z bledem aby sprawdzil dane? Czy moze rozwiazac to w jeszcze inny sposob?
Tylko co wowczas z logowaniem?
Go to the top of the page
+Quote Post
viking
post 28.04.2016, 10:44:38
Post #7





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


Logowanie i wszystkie formularze powinny zawierać niezależną walidację danych. Sam logger - poczytaj o PSR-3. Jest kilka projektów które możesz wykorzystać do zapisywania danych. Natomiast cała aplikacji może być dodatkowo toczona blokiem try/catch jeśli chcesz łapać pominięte gdzieś wcześniej.
Pamietaj że możesz rzucać wielokrotnie:

  1. try {
  2. } catch(\Exception $ex) {
  3. Logger::warn($ex->getMessage());
  4. throw $ex;
  5. }


--------------------
Go to the top of the page
+Quote Post
q.michal
post 28.04.2016, 11:33:43
Post #8





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

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


Tak, to wszystko jest jasne.
Bardziej chodzilo mi oto, aby kazdy wyjatek (bez wyjatkow tongue.gif) zostal zalogowany.
Jezeli wszystkie bylyby obsluzone przez zarejestrowanego handlera, o wystarczyloby w nim dodac logowanie.
Ale jezeli uzyje try{} catch{}, to taki wyjatek nie przejdzie przez handler i nie zostanie zapisany do loga.

Do czego zmierzam. Rozwazmy 2 przypadki:
1) Rzucamy wyjatek, obsluguje go handler, zapisywany jest do loga i uzytkownik dostaje blad na klate.
2) Rzucamy wyjatek, lapiemy go w bloku catch {}, wyswietlamy blad uzytkownikowi i kazemy go poprawic. W tym przypadku rowniez chcialbym go zalogowac do pliku.

Najlepiej gdyby dalo sie to obsluzyc juz w core, tak jak napisal com.
Pytanie jak to najlepiej rozwiazac?
Go to the top of the page
+Quote Post
Skie
post 28.04.2016, 13:53:24
Post #9





Grupa: Zarejestrowani
Postów: 555
Pomógł: 84
Dołączył: 20.02.2008
Skąd: Małopolska

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


Po pierwsze to taki wyjątek może przejsć przez catch, w prosty sposób:

Kod
try {
   // businness logic
} catch (Exception $ex) {
   // do something with $ex
   throw $ex;
}


A po drugie najlepiej byłoby w Core umieścić coś takiego:

Kod
$exceptionManager = new ExceptionManager(new MyStrategyForException());

try {
   // business logic
} catch (Exception $ex)
   $exceptionManager->handle($ex);
}


Wszystkie nieobslużone przez logikę biznesową excetpiony lecą do managera, który wg. użytej strategii decyduje co z nimi zrobić. Możesz tutaj wybrać tak jak chciałeś co chcesz zrobicz danym wyjatkiem - wyświetlić, zalogować, zapisać do db - ew. parę z tych rzeczy jednocześnie.

Ten post edytował Skie 28.04.2016, 14:25:06


--------------------
Wieloprocesowość i wielowątkowość w PHP, poznaj Kraken PHP!
Serwer HTTP i WebSocket w PHP | Promise/A+
Strona Domowa | Elradia MMORPG
FireFox: make the web better.
Go to the top of the page
+Quote Post
nospor
post 28.04.2016, 14:13:05
Post #10





Grupa: Moderatorzy
Postów: 36 455
Pomógł: 6292
Dołączył: 27.12.2004




@q.michal czy ty tez odnosisz wrazenie ze nikt nie czyta co piszesz tylko jak mantra powtarzaja w kolko to samo?


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
com
post 28.04.2016, 19:24:26
Post #11





Grupa: Zarejestrowani
Postów: 3 033
Pomógł: 366
Dołączył: 24.05.2012

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


no przecież po to robisz handler żeby zalogować te wyjątki, ale nie budował bym na nieobsłużonych wyjątkach systemu, w sensie bez kontroli tego, wiec jak potrzeba komunikat dla usera to wtedy po prostu bym to obsłużył odpowiednim warunkiem i tyle.
Go to the top of the page
+Quote Post
q.michal
post 28.04.2016, 20:00:23
Post #12





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

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


Odnosze wrazenie ze nie do konca sie zrozumielismy.
Owszem,w samym Core tak, to wszystko co piszecie jest prawda, ale:

Cytat(viking @ 28.04.2016, 11:44:38 ) *
Logowanie i wszystkie formularze powinny zawierać niezależną walidację danych.

Jak uzytkownik wpisze "loclahost" zamiast "localhost" to w zaden sposob tego nie zwalidujesz.

Cytat(com @ 28.04.2016, 20:24:26 ) *
no przecież po to robisz handler żeby zalogować te wyjątki


To prawda, dla core. Jezeli metoda Database::connect() bedzie rzucac wyjatkiem i nastapi blad podczas polaczenia do bazy danych, bez ktorej aplikacja nie moze dzialac, to handler go przechwyci, zaloguje i wyrzuci blad. Natomiast, jezeli piszac instalator do aplikacji uzyje nastepujacego kodu:

  1. try {
  2. $db->connect();
  3. }
  4. catch(Exception $e) {
  5. // przekieruj usera ponownie do formualarza konfiguracji aby poprawil dane (np. literowke w loginie lub hasle)
  6. }


to w tym wypadku, exception rzucony przez Database::connect() nie zostanie obsluzony przez handler.
Tworzac framework, wolalbym w tym miejscu nie polegac na 2 osobie, ze zadba, aby przed komentarzem umiescic wpis w logu, czy rzucic inny wyjatek. Tej osobie bedzie zalezec na tym, aby user dostal komunikat z bledem - niekoniecznie na osobnej stronie - byc moze tuz nad formularzem.

Byc moze to w metodzie Database::connect() powinno zawierac sie logowanie... Tego wlasnie chcialbym sie dowiedziec o poznac Wasza opinie.
Go to the top of the page
+Quote Post
com
post 28.04.2016, 20:17:49
Post #13





Grupa: Zarejestrowani
Postów: 3 033
Pomógł: 366
Dołączył: 24.05.2012

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


Ale pytanie czy robisz system dla kogoś kto ma pojęcie czy dla kompletnego żółtodzioba.

Tylko czy ten instalator to nadal jest cześć fw, czy to wgl jest wyizolowane, bo jak jest część fw to powinno to być raczej spójne nie uważasz?

Druga sprawa, że instalator odpalasz raz i apka żyje wiec on ma małe znaczenie raczej. A takie dane jak połączenie to wystarczy zrobić prosty test czy je ma i jak nie nawiąże to mu rzucasz tym co trzeba i tyle.

Raczej się powinno składać obiekty, wiec fajnie jakby DB połączenie otrzymało.


I lepiej nie uzależniać od logowania DB, ponieważ po pierwsze co w przypadku jak zechcesz je wymienić, albo wymienić klasę do obsługi DB. System powinniśmy budować tak, żeby dało się łatwo jeden moduł wymienić na inny. A logi systemu to nie zadanie bazy danych tylko systemu wiec bym od nich jej nie uzależniał. Zasadza pojedynczej odpowiedzialności wink.gif

Ten post edytował com 28.04.2016, 20:15:00
Go to the top of the page
+Quote Post
viking
post 28.04.2016, 20:30:19
Post #14





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


Cytat(q.michal @ 28.04.2016, 21:00:23 ) *
Jak uzytkownik wpisze "loclahost" zamiast "localhost" to w zaden sposob tego nie zwalidujesz.


A dlaczego mam tego nie zwalidować? Pierwszy z brzegu https://github.com/zendframework/zend-valid...rc/Hostname.php
Widzę że dalsze twoje problemy też wynikają z błędnej walidacji danych wejściowych.


--------------------
Go to the top of the page
+Quote Post
q.michal
post 28.04.2016, 21:10:39
Post #15





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

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


Cytat(viking @ 28.04.2016, 21:30:19 ) *
A dlaczego mam tego nie zwalidować? Pierwszy z brzegu https://github.com/zendframework/zend-valid...rc/Hostname.php
Widzę że dalsze twoje problemy też wynikają z błędnej walidacji danych wejściowych.

Wiesz ze hostname moze byc dowolny?
Wiesz ze "vfdsikjfv" tez moze byc poprawnym hostname?
Wiesz ze na tym hoscie moze nie nasluchiwac zadna baza, na zadnym porcie?
Wiesz ze baza moze nasluchiwac na dowolnym porcie, nie tylko domyslnym?

Suma sumarum - nie jestes w stanie tego wszystkie zweryfikowac, nie probujac nawiazac polaczenia.

Cytat(com @ 28.04.2016, 21:17:49 ) *
Zasadza pojedynczej odpowiedzialności wink.gif

I tego bede sie trzymal. Dzieki!

Ten post edytował q.michal 28.04.2016, 21:34:18
Go to the top of the page
+Quote Post
viking
post 29.04.2016, 06:12:43
Post #16





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


Wiem, i wszystkie typy ta klasa zwaliduje wliczając twoje własne w /etc/hosts
Czy port jest otwarty możesz zweryfikować choćby za pomocą fsockopen.
Tylko jaki jest sens tworzenia instalatora który nie sprawdzi czy wprowadzony config db powoduje nawiązanie połączenia z bazą?
Dla mnie cały instalator może być stworzony spójnie w ramach aplikacji. Ty traktujesz go chyba jako całkowicie oddzielny byt.


--------------------
Go to the top of the page
+Quote Post
Pyton_000
post 29.04.2016, 07:26:18
Post #17





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Imho połączenie z BD powinno być sprawdzane jedynie poprzez połączenie do niej i ew. sprawdzenie czy odpowiednia baza się w niej znajduje. Nie ma najmniejszego sensu sprawdzanie składowych połączenia bo najzwyczajniej w świecie na różnych systemach różnie się to robi. Po co komplikować sobie życie? KISS Twoim bratem/siostrą.
Go to the top of the page
+Quote Post
q.michal
post 29.04.2016, 07:50:27
Post #18





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

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


Cytat(viking @ 29.04.2016, 07:12:43 ) *
Wiem, i wszystkie typy ta klasa zwaliduje wliczając twoje własne w /etc/hosts
Czy port jest otwarty możesz zweryfikować choćby za pomocą fsockopen.
Tylko jaki jest sens tworzenia instalatora który nie sprawdzi czy wprowadzony config db powoduje nawiązanie połączenia z bazą?
Dla mnie cały instalator może być stworzony spójnie w ramach aplikacji. Ty traktujesz go chyba jako całkowicie oddzielny byt.


Nawet jesli fsockopen nawiaze jakies polaczenie, to dalej nie masz pewnosci ze to jest baza, a nie jakas inna usluga. Bo moze jakis debil wpisal port 22 i podlaczyl sie do ssh?
Nie ma sensu walidowanie takich danych bo nie jestes w stanie w 100% sprawdzic ich poprawnosci.
Nie traktuje instalatora jako oddzielny byt. Jest to jedynie przyklad, pokazujacy ze nie zawsze wyjatek rzucony przy probie nawiazania polaczenia z baza danych powinien konczyc sie strona z bledem.

Ale moze w takim razie inaczej. Wyjatki sa modne, bledy sa pase. W takim razie mozna pokusic sie o dopisanie error handlera, ktory wszystkie bledy automagicznie przekonwertuje na wyjatek.
I co jesli poleci E_WARNING? Zostanie obsluzony w dokladnie taki sam sposob jak E_ERROR. O ile w przypadku bledu mozemy chciec wyswietlic strone z bledem, o tyle glupim pomyslem jest zatrzymywanie aplikacji na byle warningu, juz nie wspominajac o E_NOTICE.

Ten post edytował q.michal 29.04.2016, 09:40:35
Go to the top of the page
+Quote Post
viking
post 29.04.2016, 14:00:36
Post #19





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


No ale dalej nie rozumiem esencji problemu. Masz jakiś instalator, niech będzie że krok 1 to formularz z danymi do bazy i coś tam jeszcze. User wysyła dane do tej samej strony.

  1. if POST i dane z forma są poprawne
  2. try spróbuj nawiązać połączenie, zapisz config jako array/ini/xml do pliku/bazy
  3. catch utwórz logger (nawiązując nawet kolejne połączenie z inną bazą do logów), zapisz błąd, wypisz do widoku komunikaty, nigdzie nie przekierowuj


jeśli tworzysz aplikację na zasadzie
  1. $app = new Application;
  2. $app->start();


to równie dobrze możesz ten kod też objąć try/catch z logowaniem błędów.
W ogólnej zasadzie wyjątki powinny być, że tak powiem, blokowe czyli ponieważ sygnalizują jakiś nieprawidłowy stan w jednym miejscu to dokładnie tam powinny być obsłużone a nie 10 bloków try wyżej. Własny exception handler może być problematyczny i niespójny.


--------------------
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 Wersja Lo-Fi Aktualny czas: 24.04.2024 - 11:01