Для проекта (который касается свойств недвижимости) я включил контактную форму, в которой посетитель может связаться с брокером недвижимости, если посетитель заинтересован купить / нанять недвижимость.
Я использую Symfony2 и его библиотеку. Для контактной почты я использую библиотеку Swiftmailer. Ну, у меня есть следующий код, который обрабатывает форму submit. там я создаю почтовый объект для отправки писем. Он работает, но я хочу предоставить службу разрешения ошибок, если есть проблемы с хостом smtp от отправителя / получателя.
Вот код,
$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("Ymd 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("Ymd 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'] ['sender'] = mailaddress из host / $ contactinfo ['contactmail'] = mailaddress с посетителя сайта (отправлено в контактной форме))
Теперь, когда хост smtp не работает, Swiftmailer отправляет исключение, но блок try-catch НЕ ловит его. Функция просто продолжается. Даже корневой блок try-catch (в app.php) тоже не улавливает его. В результате этого на веб-странице появляется большая ошибка PHP, чего не должно быть. Сообщение от него описано ниже,
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>
Кто-нибудь знает, почему блок catch try не улавливает настраиваемое исключение? Я изучил файлы классов и прогресс, но я не вижу никаких необычных действий.
Я надеюсь, что кто-то может прийти к решению, потому что ошибки PHP не должны появляться на страницах сайта.
удалить из вашего config.yml spool: { type: memory }
Тогда вам нужно будет добавить try catch this this
try{ $mailer = $this->getMailer(); $response = $this->getMailer()->send($message); }catch(\Swift_TransportException $e){ $response = $e->getMessage() ; }
Когда вы делаете $app['mailer']->send($mail);
сообщение электронной почты не отправляется в этот момент, если вы включили буферизацию. См. http://symfony.com/doc/current/cookbook/email/spool.html.
Если у вас есть настройка по умолчанию для spool: { type: memory }
, при \Swift_TransportException
будет \Swift_TransportException
во время фазы завершения ядра. Один из способов – отключить буферизацию (но тогда ваши пользователи могут подождать, пока отправлено электронное письмо), или вы можете сделать свой собственный eventlistener для обработки исключения. http://symfony.com/doc/current/cookbook/service_container/event_listener.html
Я столкнулся с этой проблемой в Laravel 4.2, когда я добавил SwiftMailerHandler в Monolog, чтобы он отправил мне по электронной почте все, что было зарегистрировано на определенном уровне или выше. Мне не удалось поймать исключение в обработчике, и он был отброшен обратно в браузер. Я решил это путем подкласса 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; } } }
Этот обработчик захватывает исключение SwiftMailer и записывает его на критический уровень, чтобы он не потерялся. Я не получаю сообщение об этом, но, по крайней мере, он находится в журнале.
Я с удивлением обнаружил, что SwiftMailerHandler не предложил внедрить обработчик исключений в метод отправки, но, к счастью, код написан достаточно хорошо, чтобы сделать это решение довольно простым.
Отлично работает и до сих пор не беспокоил меня.
У вас есть последняя версия swiftmailer? Строка 226 StreamBuffer.php не вызывает никаких исключений. Эта версия от 2 лет назад делает исключение на этой конкретной строке.
Я попытаюсь использовать последнюю версию, прежде чем погрузиться в проблему более глубоко.
SCREAM – это настройка XDebug, которая позволяет видеть ошибки, которые обычно захватываются или подавляются. (Используя, например, @).
xdebug.scream = 1
в вашем php.ini и установите значение 0.
вы можете попробовать под кодом для пользовательской ошибки:
public function render($request, Exception $exception) { if ($exception instanceof \Swift_TransportException) { return response()->view('errors.404'); } return parent::render($request, $exception); }