dongying3830 2013-07-17 01:19
浏览 63

swiftmailer Swift_TransportException被try-catch块无法捕获

For a project (which is about estate properties) i have included a contact form where a visitor can contact an estate broker if the visitor is interested to buy/hire an estate property.

I am using Symfony2 and its library. For the contact mail, i am using the Swiftmailer library. Well, i have the next code which handles the form submit. there, I create a mail object to be able to send mails. It works, but i want to provide a error resolving service if there are problems with the smtp host from sender/receiver.

Here is the code,

$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']['sender'] = mailaddress from host / $contactinfo['contactmail'] = mailaddress from site visitor (submitted in contact form))

Now, when the smtp host doesn't work, Swiftmailer DOES send an exception, but the try-catch block ISN'T catching it. The function is just being continued. Even the root try-catch block (in app.php) isn't catching it too. As a result of this, you see a large PHP error on the webpage, which shouldn't happen. The message from it is described here below,

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>

Does anyone know why the try catch block isn't catching the custom exception ? I have investigated the class files and the progress, but i don't see any unusual activity.

I hope that someone can come with a solution to this because PHP errors shouldn't appear on site pages.

展开全部

  • 写回答

7条回答 默认 最新

  • duanmiexi2275 2013-07-29 02:07
    关注

    Sure you have the latest version of swiftmailer? Line 226 of StreamBuffer.php doesn't throw any exception. This version from 2 years ago does throw the exception on that specific line.

    I'd try running the latest version before diving into the issue more deeply.

    评论
  • doulu8415 2013-11-19 06:37
    关注

    SCREAM is a setting of XDebug that allows to see errors that are normally caught or suppressed. (Using @, for example.) Search for

    xdebug.scream = 1
    

    in your php.ini and set this to 0.

    评论
  • drxv39706 2014-02-20 12:22
    关注

    remove from your config.yml spool: { type: memory }

    Then you will be to add try catch like this

        try{
            $mailer = $this->getMailer();
            $response = $this->getMailer()->send($message);
        }catch(\Swift_TransportException $e){
            $response = $e->getMessage() ;
        }
    
    评论
  • dongpo5264 2014-10-11 13:52
    关注

    When you do $app['mailer']->send($mail); the email message is not being sent at that point if you have spooling turned on. See http://symfony.com/doc/current/cookbook/email/spool.html

    If you have the default setting of spool: { type: memory }, the \Swift_TransportException will be thrown during the kernel termination phase, after you controller has exited. One way around this is to turn off the spooling (but then your users might have to wait while the email is sent), or you can make your own eventlistener to handle the exception. http://symfony.com/doc/current/cookbook/service_container/event_listener.html

    评论
  • dongtan6336 2015-09-18 12:54
    关注

    I ran into this problem in Laravel 4.2 when I added a SwiftMailerHandler to Monolog so it would email to me anything logged at a certain level or above. There was no way for me to catch the exception in the handler and it was thrown back to the browser. I solved it by subclassing 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;
          }
        }
      }
    

    This handler catches the SwiftMailer exception and logs it at the critical level so it's not lost. I don't get an email about it but at least it's in the log.

    I was surprised to find SwiftMailerHandler offered no way to inject an exception handler into the send method but fortunately the code is written well enough to make this solution pretty simple.

    Works great and has given me no trouble so far.

    展开全部

    评论
  • douwen9343 2017-08-30 02:59
    关注

    you can try below code for custom error:

    public function render($request, Exception $exception)
    {
         if ($exception instanceof \Swift_TransportException) {
         return response()->view('errors.404');
    }
         return parent::render($request, $exception);
    }
    
    评论
  • duancai1904 2019-08-02 08:15
    关注

    Try to put a backslash infront of Exception.

    catch(\Exception $e)
    

    A \ (backslash) before the beginning of a class name represents the Global Namespace.

    Using a backslash will ensure that the Exception is called within the global namespace.

    评论
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部