Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony]Wyjątki try catch
Forum PHP.pl > Forum > PHP > Frameworki
blackroger
Mam problem. Otóż mam takie coś:

  1. try
  2. {
  3. $con->beginTransaction();
  4.  
  5. $r = new Rejestracja();
  6.  
  7. $r->setLogin($request->getParameter('login'));
  8. $r->setHaslo($request->getParameter('haslo'));
  9. $r->setImie($request->getParameter('imie'));
  10. $r->setNazwisko($request->getParameter('nazwisko'));
  11. $r->setMiasto($request->getParameter('miasto'));
  12. $r->setMail($request->getParameter('mail'));
  13. $r->setData(date("Y-m-d"));
  14.  
  15. $r->save();
  16. $con->commit();
  17.  
  18. return $this->forward('register', 'thank_you');
  19. } catch(Exception $e)
  20. {
  21. $con->rollback();
  22.  
  23. return $this->forward('register', 'error');
  24. //throw($e);
  25. }
  26. //return $this->forward('register', 'thank_you');

Wszystko działa dobrze (bez throw()), gdy daje return $this->forward('register', 'thank_you'); poza blokiem try. Gdy jest w środku - pojawia się warning, dochodzi do poprawnego przekierowania a następnie catch przechwytuje i przekierowuje do error:


Dziękujemy!

Warning: Cannot modify header information - headers already sent by (output started at /usr/share/php/symfony/response/sfResponse.class.php:105) in /usr/share/php/symfony/response/sfWebResponse.class.php on line 335

Warning: Cannot modify header information - headers already sent by (output started at /usr/share/php/symfony/response/sfResponse.class.php:105) in /usr/share/php/symfony/response/sfWebResponse.class.php on line 349
Błąd transakcji!


Gdy używam throw() problem rozwiązuje się częściowo, gdyż warningi nie występują, ale w przypadku błędu blok catch przechwytuje wyjątek a throw wyrzuca błąd uniemożliwiając przeforwardowanie return $this->forward('register', 'error'); Ustawienie throw() przed czy po return forward nie załatwia sprawy.

Zaznaczam raz jeszcze, że problem występuje tylko i wyłącznie przy zastosowaniu try, catch...
Symfony Framework.
krowal
Gdzieś niepotrzebnie wyrzucasz 'Dziękujemy!' od razu na ekran a symfony nie lubi echo w modelach i w akcjach winksmiley.jpg
Ociu
Przenoszę do Framoworki.
destroyerr
Na początku napiszę tylko, że związek z symfony moim zdaniem jest mizerny.

Zakładam, że korzystasz z Propela, a kod który podałeś to kod Twojej akcji. Zakładam też, że klasa Rejestracja to klasa modelu, jeśli tak, to w takim razie otwórz sobie plik: lib/model/om/BaseRejestracja.php i poszukaj sobie metody save (zwróć uwagę na obsługę transakcji).

Cały Twój problem bierze się z braku walidacji danych (lepiej gdybyś stworzył do tego formularz). Trafiają się pewnie dane, których baza nie chce przyjąć dlatego dostajesz wyjątek. Przy dobrej walidacji, wyjątek będzie tylko w sytuacji wyjątkowej i wtedy użytkownik może zobaczyć stronę błędu (dodatkowa obsługa wyjątku może zostać pominięta).

Po poprawnym wykonaniu akcji z zapisem lepiej zrobić redirect, a nie forward.
Co do ostrzeżenia - nie będę wróżył skąd się wzięło.
blackroger
Jeżeli chodzi o walidację to jest, była i będzie w lib/form. Nie będę jej całej tu umieszczać, chyba że ktoś stwierdzi, że to może pomóc w rozwiązaniu problemu. Przy redirect problem nie występuje. Zastanawia mnie tylko dlaczego przy forward dzieją się takie dziwne rzeczy i to tylko w przypadku zastosowania try,catch...

Przed chwilą znalazłem link na forum:
http://forum.php.pl/lofiversion/index.php/t124562.html

Jest tu poruszany dokładnie ten sam problem, jakkolwiek nie został on tu również rozwiązany (przyczyna warningu jest nieznana).
destroyerr
Tylko co z tego, że ta walidacja jest w jakimś tam folderze, skoro w podanym przez Ciebie kodzie nie jest ona wykorzystana?!

W podanym przez Ciebie wątku problem nie został rozwiązany z przyczyn oczywistych, autor nie podał informacji o tym jaki dostaje wyjątek. Obaj chcecie złapać wszystkie wyjątki, co nie ma najmniejszego sensu. Symfony jest skonstruowane w ten sposób, że forward jest wymuszony przez wyjątek: sfForwardException. Ty go przechwytujesz i forward się nie odbywa, a więc winne jest to o czym pisałem między innymi w poprzednim poście.
blackroger
Tak dla wyjaśnienia sprawy z walidacją:

  1. public function executeIndex(sfWebRequest $request)
  2. {
  3. $form = new RegisterForm();
  4.  
  5. if($this->getRequest()->isMethod('post'))
  6. {
  7. $form->bind(array('login'=>$this->getRequest()->getParameter('login'),
  8. 'haslo'=>$this->getRequest()->getParameter('haslo'),
  9. 'powtorz'=>$this->getRequest()->getParameter('powtorz'),
  10. 'imie'=>$this->getRequest()->getParameter('imie'),
  11. 'nazwisko'=>$this->getRequest()->getParameter('nazwisko'),
  12. 'miasto'=>$this->getRequest()->getParameter('miasto'),
  13. 'mail'=>$this->getRequest()->getParameter('mail')
  14. ));
  15.  
  16.  
  17. if($form->isValid())
  18. {
  19. $data = $form->getValues();
  20.  
  21. $con = Propel::getConnection();
  22.  
  23. (.....tą część już podałem wcześniej)
  24.  
  25. }//koniec valid if
  26. }//koniec request if
  27.  
  28. $this->form = $form;
  29. }//koniec executeIndex
  30.  


Nie będę pokazywał registerForm bo jest za długi. Dzięki destroyerr za zainteresowanie tematem. Jeżeli w symfony forward wymusza wyjatek przekierowania sfForwardException to jak teraz zrobić aby przechwytywać wszystkie wyjątki z wyjątkiem niego. Wiem, że można sprawę załatwić na 10 innych sposobów ale mnie interesuje konkretnie ten...winksmiley.jpg
-=Peter=-
A po co wszystkie? wysterczy jeden (dla ułatwienia: bodajże PropelException)...
destroyerr
Oh, moim zdaniem robisz błąd i pakujesz się w głupią sytuację, no ale jeśli tak bardzo chcesz:
  1. <?php
  2.  
  3.  
  4. try
  5. {
  6. //...
  7. $this->forward('register', 'thank_tou'); //Upierasz się w tym miejscu na forward, a powinien być redirect!
  8. }
  9. catch(PropelException $exception)
  10. {
  11. $this->forward('register', 'error');
  12. }
  13. catch(sfForwardException $exception)
  14. {
  15. throw $exception;
  16. }
  17.  
  18. ?>

Twoja akcja jest w tym momencie niesamowice długa, a wystarczyło:
  1. <?php
  2.  
  3. public function executeIndex(sfWebRequest $request)
  4. {
  5. $form = new RegisterForm();
  6. //$form->getWidgetSchema()->setNameFormat('rejestracja[%s]'); //Ewentulnie możesz dodać to tutaj, choć lepiej w formularzu.
  7. if($request->isMethod('post')
  8. {
  9. $form->bind($request->getParameter('rejestracja'));
  10. if($form->isValid())
  11. {
  12. $form->save(); //Taki zapis jeśli dziedziczy Twój formularz po sfFormPropel
  13. /**
  14. a jeśli nie to tak (łapanie wyjątku dodałem specjalnie dla Ciebie):
  15. $rejestracja = new Rejestracja();
  16. $rejestracja->fromArray($form->getValues(), BasePeer::TYPE_FIELDNAME);
  17. try
  18. {
  19. $rejestracja->save();
  20. }
  21. catch(PropelException $exception)
  22. {
  23. }
  24. */
  25. $this->getUser()->setFlash('notice', 'Rejestracja przebiegła pomyślnie');
  26.  
  27. $this->rediret('@register_thank_you');
  28. }
  29. else
  30. {
  31. $this->forward('register', 'error');
  32. }
  33. }
  34.  
  35. $this->setVar('form', $form);
  36. }
  37. ?>

blackroger
Ok...dzięki za odpowiedzi...wiem, że może głupio się upierałem ale takie rozwiązanie znalazłem w pewnej książce (dla symfony 1.1) i po prostu wywnioskowałem, że autor zamieścił kod, który zawiera błędy i nie jest stricte edukacyjny winksmiley.jpg Zresztą to nie pierwszy, który tam znalazłem.
destroyerr
Mały OT: nie wiem jak ktoś mógł wydać książkę dla symfony 1.1. Już sam pomysł na takie wydawnictwo sugeruje niepełną znajomość tematu. Jeśli faktycznie autor wypisuje tam takie rzeczy, to tylko potwierdza się moje zdanie.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.