2013-07-17 48 views
5

W przypadku projektu (dotyczącego nieruchomości) umieściłem formularz kontaktowy, w którym użytkownik może skontaktować się z pośrednikiem w obrocie nieruchomościami, jeśli użytkownik jest zainteresowany zakupem/wynajęciem nieruchomości.swiftmailer Swift_TransportWyjątek zostaje zablokowany przez blok próbny catch

Używam Symfony2 i jej biblioteki. W przypadku poczty kontaktowej korzystam z biblioteki Swiftmailer. Mam kolejny kod, który obsługuje formularz przesyłania. tam tworzę obiekt poczty, aby móc wysyłać maile. Działa, ale chcę zapewnić usługę rozwiązywania błędów, jeśli występują problemy z hostem smtp od nadawcy/odbiorcy.

Oto kod,

$data = $contactForm->getData(); 
try { 
    // create body text 
    $body = $app['twig']->render('mailTemplate.twig', array('data' => $data, 'immoid' => $immoID)); 
    // set mail 
    $mail = \Swift_Message::newInstance() 
     ->setSubject('Contact reaction on your immo offer.') 
     ->setFrom($app['swiftconfig']['sender']) 
     ->setTo($contactinfo['contactmail']) 
     ->setBody($body, 'text/html'); 
    // send mail 
    $app['mailer']->send($mail); 
    // redirect if successfull 
    $app->redirect($app['url_generator']->generate('immoDetail', array('immoID' => $immoID))); 
} 
catch (Swift_TransportException $STe) { 
    // logging error 
    $string = date("Y-m-d H:i:s") . ' - ' . $STe->getMessage() . PHP_EOL; 
    file_put_contents("errorlog.txt", $string, FILE_APPEND); 
    // send error note to user 
    $errorMsg = "the mail service has encountered a problem. Please retry later or contact the site admin."; 
} 
catch (Exception $e) { 
    // logging error 
    $string = date("Y-m-d H:i:s") . ' - GENERAL ERROR - ' . $e->getMessage() . PHP_EOL; 
    file_put_contents("errorlog.txt", $string, FILE_APPEND); 
    // redirect to error page 
    $app->abort(500, "Oops, something went seriously wrong. Please retry later !"); 
} 

($ app [ 'swiftconfig'] [ 'nadawca'] = MailAddress z hosta/$ ContactInfo [ 'contactmail'] = adresu pocztowego ze strony użytkownika (złożone w formularz kontaktowy))

Teraz, gdy host smtp nie działa, Swiftmailer wysyła wyjątek, ale blok catch próbuje go NIE przechwycić. Funkcja jest właśnie kontynuowana. Nawet główny blok try-catch (w app.php) też go nie łapie. W wyniku tego na stronie pojawia się duży błąd PHP, co nie powinno się zdarzyć. Wiadomość od niego jest opisana poniżej:

SCREAM: Error suppression ignored for 
--- 
Fatal error: Uncaught exception 'Swift_TransportException' with message ' in C:\...\vendor\swiftmailer\swiftmailer\lib\classes\Swift\Transport\StreamBuffer.php on line 266 
--- 
Swift_TransportException: Connection could not be established with host <output omitted> 

Czy ktoś wie, dlaczego blok catch try nie chwyta niestandardowego wyjątku? Zbadałem pliki klas i postępy, ale nie widzę żadnej niezwykłej aktywności.

Mam nadzieję, że ktoś może znaleźć rozwiązanie, ponieważ błędy PHP nie powinny pojawiać się na stronach witryny.

+0

Czy jesteś pewien, że WYJĄTKIEM w tej części kodu? Nie widzę nic paskudnego. –

+5

Spróbuj 'catch (\ Swift_TransportException $ e)' –

+0

@ Arkadiusz'flies'Rzadkowolski: Tak. Ta funkcja jest jedyną, w której używam biblioteki Swiftmailer. Powyższy blok kodu pojawia się w żądaniu POST: if ('POST' == $ app ['request'] -> getMethod()) {...} – KarelG

Odpowiedz

0

Na pewno masz najnowszą wersję Swiftmailer? Line 226 of StreamBuffer.php nie rzuca żadnego wyjątku. This version from 2 years ago rzuca wyjątek na tę konkretną linię.

Próbuję uruchomić najnowszą wersję, zanim głębiej zanurzę się w problemie.

+0

Ponownie zaktualizowałem dostawcę ([swiftmailer jest na v5.0.1] (https://github.com/swiftmailer/swiftmailer/blob/master/VERSION) .Teraz mam najnowszą wersję: 5.0.1 (z VERSION -file - "Swift-5.0.1"), ale wciąż wywołuje ten sam błąd (pochodzi z [Line256 of SteamBuffer.php] (https://github.com/swiftmailer/swiftmailer/blob/master/lib/classes /Swift/Transport/StreamBuffer.php#L259) btw.) – KarelG

0

SCREAM to ustawienie XDebug umożliwiające wyświetlanie błędów, które normalnie są przechwytywane lub pomijane. (Za pomocą przycisku @, na przykład.) Szukane

xdebug.scream = 1 

w php.ini i ustawić na 0.

10

usunąć z config.yml spool: { type: memory }

Wtedy będziesz aby dodać try catch jak ten

try{ 
     $mailer = $this->getMailer(); 
     $response = $this->getMailer()->send($message); 
    }catch(\Swift_TransportException $e){ 
     $response = $e->getMessage() ; 
    } 
3

Kiedy robisz $app['mailer']->send($mail); wiadomość e-mail nie jest wysłał t ten punkt, jeśli buforowanie jest włączone. Patrz http://symfony.com/doc/current/cookbook/email/spool.html

Jeśli masz domyślne ustawienie , \Swift_TransportException zostanie wygenerowany podczas fazy zakończenia jądra, po wyjściu kontrolera. Jednym ze sposobów obejścia tego problemu jest wyłączenie buforowania (ale wtedy użytkownicy mogą czekać na wysłanie wiadomości e-mail) lub można utworzyć własną listę zdarzeń, aby obsłużyć wyjątek.http://symfony.com/doc/current/cookbook/service_container/event_listener.html

1

Wpadłem na ten problem w Laravel 4.2, kiedy dodałem do Monologa SwiftMailerHandler, aby wysyłał mi e-mailem wszystko, co było zalogowane na pewnym poziomie lub wyższym. Nie było sposobu, aby złapać wyjątek w programie obsługi i został on wrzucony do przeglądarki. Rozwiązałem go przez instacji SwiftMailerHandler:

<?php 
/******************************************************************************* 
* $Id: LogMailer.php 12152 2015-09-15 00:42:38Z sthames $ */ 
/** 
* Subclass of Monolog SwiftMailerHandler that will catch exceptions SwiftMailer 
* throws during the send. These exceptions are logged at the critical level. 
* Without this, such exceptions are reported back to the browswer. 
*******************************************************************************/ 
class LogMailer extends \Monolog\Handler\SwiftMailerHandler 
    { 
    /** Flag set when logging an exception during send. */ 
    protected $dont_mail = false; 

    /** Overloads sender to catch and log errors during the send. */ 
    protected function send($content, array $records) 
    { 
    try 
     { 
     if (!$this->dont_mail) 
     parent::send($content, $records); 
     } 
    catch(\Exception $e) 
     { 
     $this->dont_mail = true; 
     Log::critical($e->getMessage()); 
     $this->dont_mail = false; 
     } 
    } 
    } 

Ten uchwyt łapie wyjątek SwiftMailer i rejestruje go na poziomie krytycznym więc to nie jest stracone. Nie otrzymuję wiadomości e-mail o tym, ale przynajmniej jest w dzienniku.

Byłem zaskoczony, gdy zauważyłem, że SwiftMailerHandler nie zaoferował żadnego sposobu na wprowadzenie obsługi wyjątku do metody wysyłania, ale na szczęście kod został napisany na tyle dobrze, aby to rozwiązanie było całkiem proste.

Działa świetnie i nie sprawił mi żadnych problemów.

0

można spróbować poniżej kod do własnego błędu:

public function render($request, Exception $exception) 
{ 
    if ($exception instanceof \Swift_TransportException) { 
    return response()->view('errors.404'); 
} 
    return parent::render($request, $exception); 
}