Не можете поймать исключение SwiftMailer? - PullRequest
0 голосов
/ 23 января 2019

Я использую SwiftMailer (автономно).

Приведенный ниже код работает нормально, но когда я ввожу недопустимые учетные данные SMTP, такая ошибка отображается со всей трассировкой стека:

Failed to authenticate on SMTP server with username "MYUSERNAME" using 3 possible authenticators. Authenticator CRAM-MD5 returned Swift_TransportException: Expected response code 235 but got code "535", with message "535 5.7.0 Invalid login or password
" in /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php:457
Stack trace:
#0 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(341): Swift_Transport_AbstractSmtpTransport->assertResponseCode('535 5.7.0 Inval...', Array)
#1 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php(305): Swift_Transport_AbstractSmtpTransport->executeCommand('NmE0ODlmMWNmOTc...', Array, Array, false, NULL)
#2 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php(39): Swift_Transport_EsmtpTransport->executeCommand('NmE0ODlmMWNmOTc...', Array)
#3 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php(177): Swift_Transport_Esmtp_Auth_CramMd5Authenticator->authenticate(Object(Swift_SmtpTransport), 'MYUSERNAME', 'MYPASSWORD')
#4 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php(371): Swift_Transport_Esmtp_AuthHandler->afterEhlo(Object(Swift_SmtpTransport))
#5 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(148): Swift_Transport_EsmtpTransport->doHeloCommand()
#6 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php(65): Swift_Transport_AbstractSmtpTransport->start()
#7 /var/www/tester/public/index.php(32): Swift_Mailer->send(Object(Swift_Message))
#8 {main}. Authenticator LOGIN returned Swift_TransportException: Expected response code 250 but got an empty response in /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php:445
Stack trace:
#0 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(341): Swift_Transport_AbstractSmtpTransport->assertResponseCode('', Array)
#1 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php(305): Swift_Transport_AbstractSmtpTransport->executeCommand('RSET\r\n', Array, Array, false, NULL)
#2 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php(40): Swift_Transport_EsmtpTransport->executeCommand('RSET\r\n', Array)
#3 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php(177): Swift_Transport_Esmtp_Auth_LoginAuthenticator->authenticate(Object(Swift_SmtpTransport), 'MYUSERNAME', 'MYPASSWORD')
#4 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php(371): Swift_Transport_Esmtp_AuthHandler->afterEhlo(Object(Swift_SmtpTransport))
#5 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(148): Swift_Transport_EsmtpTransport->doHeloCommand()
#6 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php(65): Swift_Transport_AbstractSmtpTransport->start()
#7 /var/www/tester/public/index.php(32): Swift_Mailer->send(Object(Swift_Message))
#8 {main}. Authenticator PLAIN returned Swift_TransportException: Expected response code 250 but got an empty response in /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php:445
Stack trace:
#0 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(341): Swift_Transport_AbstractSmtpTransport->assertResponseCode('', Array)
#1 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php(305): Swift_Transport_AbstractSmtpTransport->executeCommand('RSET\r\n', Array, Array, false, NULL)
#2 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php(39): Swift_Transport_EsmtpTransport->executeCommand('RSET\r\n', Array)
#3 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php(177): Swift_Transport_Esmtp_Auth_PlainAuthenticator->authenticate(Object(Swift_SmtpTransport), 'MYUSERNAME', 'MYPASSWORD')
#4 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php(371): Swift_Transport_Esmtp_AuthHandler->afterEhlo(Object(Swift_SmtpTransport))
#5 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(148): Swift_Transport_EsmtpTransport->doHeloCommand()
#6 /var/www/tester/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php(65): Swift_Transport_AbstractSmtpTransport->start()
#7 /var/www/tester/public/index.php(32): Swift_Mailer->send(Object(Swift_Message))
#8 {main}.done

Пример кода:

<?php

try {

    $transport = (new Swift_SmtpTransport($host, $port))
        ->setUsername($user)
        ->setPassword($pass);

    $mailer = new \Swift_Mailer($transport);

    $message = (new \Swift_Message('test'))
        ->setFrom(['foo@example.com' => 'bar'])
        ->setTo(['foo@example.com'])
        ->setBody('test');

    $mailer->send($message);

} catch (\Swift_TransportException $ex) {

    echo $ex->getMessage();

} catch (\Exception $ex) {

    echo $ex->getMessage();
}

Разве не предполагается ловить исключения?

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

После долгого копания я могу согласиться с тем, что пришел к тому же выводу, что и @ gere.

Шокирующе, но $ex->getMessage(); имеет добавленную stackTrace.

Я нашелчто вы можете отключить это, закомментировав цикл foreach(), который добавляет всю эту дополнительную информацию к сообщению в одном из основных файлов SwiftMailer.Это может стать проблемой в будущем, если вы решите обновить файлы SwiftMailer, но в качестве временного исправления, если ваша файловая структура такая же, как у меня, перейдите к (для меня это была строка 187):

/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authhandler.php

и найдите функцию public function afterEhlo(Swift_Transport_SmtpAgent $agent)

В конце код выглядит так:

$message = 'Failed to authenticate on SMTP server with username "' . $this->username . '" using ' . $count . ' possible authenticators.';
foreach ($errors as $error) {
    $message .= ' Authenticator ' . $error[0] . ' returned ' . $error[1] . '.';
}

throw new Swift_TransportException($message);

и закомментируйте цикл foreach() или даже простовнутреннее выражение:

$message = 'Failed to authenticate on SMTP server with username "' . $this->username . '" using ' . $count . ' possible authenticators.';
/*foreach ($errors as $error) {
    $message .= ' Authenticator ' . $error[0] . ' returned ' . $error[1] . '.';
}*/

throw new Swift_TransportException($message);

Редактировать: я забыл упомянуть, этот код перебирает каждый из аутентификаторов, которые используются при попытках аутентификации, и выплевывает ошибки, с которыми они сталкиваются, в виде стекатрассировка, это дополнительные данные, которые вы видите.Просто для пояснения.

Редактировать 2: Это было исправлено 24 дня назад путем замены строки 182:

$errors[] = [$authenticator->getAuthKeyword(), $e];

на:

$errors[] = [$authenticator->getAuthKeyword(), $e->getMessage()];

Как показывает сообщение о коммите на git, здесь

0 голосов
/ 04 февраля 2019

Вы можете попытаться сделать то, что руководство предлагает:

Если вам нужно заранее узнать, не прошла ли аутентификация и возникнет ли исключение, позвоните по телефонуметод start () для созданного транспорта.

Таким образом, полученный код может быть:

$transport = (new Swift_SmtpTransport($host, $port))
    ->setUsername($user)
    ->setPassword($pass); 
$try {
    $transport->start();
} catch (\Swift_TransportException $ex) {
    echo $ex->getMessage();
    return; //whatever you want to do.
}
....

ОБНОВЛЕНИЕ: После дальнейшего анализа, я думаю, я его получил.Вы можете верить, что вы не поймали исключение, но на самом деле это так.Проблема в том, что метод getMessage() в Swift_TransportException возвращает полную трассировку стека (по крайней мере, в моем env с SwiftMailer 6) ... Попробуйте сделать что-то подобное в вашем блоке catch echo "Message start" . $ex->getMessage() . "Message End"; И вы должны увидеть тексты, которые выдобавлено.

ОБНОВЛЕНИЕ 2: Если вы хотите избавиться от трассировки стека в сообщении, единственное решение, о котором я могу подумать, - это создать подкласс Swift_SmtpTransport, перехватить исключение ранее и создать новое сболее короткое сообщение.Возможное решение может выглядеть следующим образом

class Better_SwiftSmtpTransport extends  Swift_SmtpTransport
{
    public function __construct(string $host = 'localhost', int $port = 25, ?string $encryption = null)
    {
        parent::__construct($host, $port, $encryption);
    }

    public function start()
    {
        try {
            return parent::start();
        }
        catch (Swift_TransportException $ex) {
            throw new Better_SwiftSmtpTransportException(
                $ex->getMessage(), 
                $ex->getCode(), 
                $ex
            );
        }
    }
}

class Better_SwiftSmtpTransportException extends Swift_TransportException
{
    public function __construct(string $message, int $code = 0, Exception $previous = null)
    {
        $message = strtok($message, "\n"); // get only the first line of the message
        parent::__construct($message, $code, $previous);
    }
}

$transport = (new Better_SwiftSmtpTransport($host, 25))
    ->setUsername($user)
    ->setPassword($password)
;
try {
    $mailer = new \Swift_Mailer($transport);
    $message = (new \Swift_Message('test'))
        ->setFrom(['foo@example.com' => 'bar'])
        ->setTo(['foo@example.com'])
        ->setBody('test');
    $mailer->send($message);

} catch (Swift_TransportException $ex) {
    echo  $ex->getMessage();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...