Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Exception handling z przywracaniem, Problem użycia restore wewnątrz handler'a (PHP 7.3.4)
session
post 17.04.2019, 02:33:02
Post #1





Grupa: Zarejestrowani
Postów: 112
Pomógł: 22
Dołączył: 11.04.2010
Skąd: Tarnów

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


Witajcie!

Przejdę od razu do rzeczy:
  1. function catchable($e) {
  2. if(get_class($e) === 'PDOException')
  3. echo 'Database problem';
  4.  
  5. restore_exception_handler();
  6. throw $e;
  7. }
  8.  
  9. function unknown($e) {
  10. echo 'Something went wrong';
  11. }
  12.  
  13. set_exception_handler('unknown');
  14. set_exception_handler('catchable');
  15.  
  16. throw new Exception('Catch me!');


Kod zwraca Uncaught Exception.

Jest to dla mnie nieoczekiwane zachowanie z kilku powodów:
1. Nie ma przeciwwskazań do wywoływania innych funkcji (również user-defined) z samego callback'a
2. set_exception_handler wywołany z poziomu handler'a zwraca prawidłową nazwę callback'a, co oznaczałoby że ma dostęp do bieżącego stosu handler'ów
3. throw ostatecznie się wykonuje i dopiero domyślny handler kończy działanie
4. użycie restore_exception_handler poza handler'em daje oczekiwany rezultat

Nie wiem zatem czy jest to problem języka, mojej interpretacji zachowania tych funkcji, czy rodzaj zabezpieczenia przed pętlą wyjątków. W dodatku myślę, że w przypadku error'ów może dziać się analogicznie.
Macie może jakieś sugestie, dlaczego wyjątek nie trafia do poprzedniego handler'a? Jakieś alternatywy dla tej funkcjonalności (poza wywoływaniem unknown na końcu catchable)?

A komu to potrzebne?
Sam fragment kodu to oczywiście koncepcja. Zamiarem jest, aby każda klasa, w której będzie to potrzebne, posiadała odrębny handler, w którym obsługiwane będą wyjątki związane z tą klasą. Natomiast główny handler aplikacji wyłapywałby wszystkie pozostałe wyjątki, tak aby zakończyć działanie w bardziej wdzięczny sposób, niż robi to domyślny handler.

EDIT: Znalazłem jeszcze notatkę sprzed 5 lat. Jak zatem rozwiązujecie obsługę wyjątków i błędów w aplikacji, tak aby handling był rozproszony? Gotta catch 'em all? tongue.gif

Ten post edytował session 17.04.2019, 02:38:07
Go to the top of the page
+Quote Post
viking
post 17.04.2019, 06:34:04
Post #2





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

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


A czemu nie zrobisz tego po prostu w odpowiednich namespace? jeśli pakiet to Cos, to klasy wyjątków w Cos\Exception. Łapanie wszystkich będzie pewnie i tak na poziomie index.php, a reszta tam gdzie wywołujesz klasę.


--------------------
Go to the top of the page
+Quote Post
session
post 17.04.2019, 11:16:30
Post #3





Grupa: Zarejestrowani
Postów: 112
Pomógł: 22
Dołączył: 11.04.2010
Skąd: Tarnów

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


Nie bardzo wiem jak można by tutaj wykorzystać namespace'y? worriedsmiley.gif Może opiszę to jeszcze od innej strony. Chciałbym zrobić jakiś wygodny exception handling, try/catchowanie tych samych wyjątków w wielu metodach jest dla mnie mało efektywne. W dodatku semantycznie przydatny byłby wielopoziomowy handling:
  1. class Database {
  2. public function __construct(){
  3. set_exception_handler([$this, 'exceptionHandler']);
  4. }
  5.  
  6. public function select(){}
  7. public function insert(){}
  8. public function update(){}
  9. public function delete(){}
  10.  
  11. public function exceptionHandler($e){
  12. restore_exception_handler();
  13. throw $e;
  14. }
  15. }
  16.  
  17. class User {
  18. public function __construct(){
  19. set_exception_handler([$this, 'exceptionHandler']);
  20. }
  21.  
  22. public function add(){ $db = new Database(); $db->insert(); }
  23.  
  24. public function exceptionHandler($e){
  25. restore_exception_handler();
  26. throw $e;
  27. }
  28. }
  29.  
  30. set_exception_handler('unknown');


I wtedy wszystkie wyjątki związane z bazą danych obsługiwane w klasie Database, a wyjątki z klasy User z fallback'iem do Database. Finalnie wszystkie pozostałe wyjątki obsługiwane przez kolejny handler.
Teoretycznie myślę, że można by zrobić customowy stos handler'ów, callback'i, metody set i restore i wykorzystać tylko jeden "oryginalny" handler, ale czy nie byłby to pewnego rodzaju overkill?
Dziwi mnie, że PHP który na kilku stronach manual'a pokazuje wykorzystanie wielu set i restore w tym przypadku nie działa w oczekiwany sposób. blink.gif

Ten post edytował session 17.04.2019, 11:23:30
Go to the top of the page
+Quote Post
viking
post 17.04.2019, 11:42:03
Post #4





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

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


Tak z ciekawości. Jak w tej swojej klasie database obsłużysz np transakcje i rollbacki? W klasie User nie powinieneś tworzyć obiektu Database tylko go wstrzyknąć. Bardziej mi to wygląda na problem z architekturą tej aplikacji.


--------------------
Go to the top of the page
+Quote Post
session
post 17.04.2019, 12:17:42
Post #5





Grupa: Zarejestrowani
Postów: 112
Pomógł: 22
Dołączył: 11.04.2010
Skąd: Tarnów

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


Ok, nie najlepszy przykład może, tak na prawdę Database byłaby singleton'em i bardziej statyczna, ale wtedy konstruktor nie miałby sensu, więc trochę dla uproszczenia poszedłem na skróty na potrzeby przykładu wink.gif Jednak dalej zastanawiają mnie te wyjątki, tym bardziej, że PHP od 7. wersji coś w tej tematyce ogólnie zmieniał.

Ten post edytował session 17.04.2019, 12:19:44
Go to the top of the page
+Quote Post
viking
post 17.04.2019, 18:13:41
Post #6





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

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


https://www.php.net/manual/en/language.errors.php7.php
Możesz wiele wyjątków na raz przez | łapać. Na pewno nie żaden singleton i na pewno nie więcej statyków tylko dependency injection. A czepiam się tego bo wyraźnie to pokazuje że masz problem z architekturą całości i prawidłowym grupowaniem funkcjonalności w zestaw klas.


--------------------
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: 19.04.2024 - 18:37