Я работал над обновлением php7, а также переместил phpmailer для загрузки через composer.
у нас есть система сборки, протестированная на Travis. мы используем grunt для запуска тестов на селен.
когда я тестирую локально (grunt test
), все тесты проходят, но когда я нажимаю на Travis (через GitHub), некоторые тесты не выполняются.
неудачные тесты возвращают следующее сообщение (в журнале Travis после установки SMTPDebug в 3):
2018-06-27 12:39:23 Соединение: открытие в smtp.sendgrid.net:587, тайм-аут = 300, options = array ()
2018-06-27 12:43:37 Ошибка подключения. Ошибка № 2: stream_socket_client (): невозможно подключиться к smtp.sendgrid.net:587 (истекло время ожидания соединения) [/var/www/includes/phpmailer/phpmailer/src/SMTP.php строка 325]
2018-06-27 12:43:37 ОШИБКА SMTP: не удалось подключиться к серверу: истекло время ожидания соединения (110)
SMTP-соединение () не удалось. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
Странно то, что некоторые проходящие тесты используют тот же код, что и провальные тесты. мы создаем экземпляр нашего объекта-оболочки с такими же атрибутами в каждом из сценариев, которые отправляют почту.
это исключение из кода, который не может отправить почту:
$mail->sendMsg($config->getOpt('site_name'),
$config->getOpt('site_email'),
$userInfo['userName'],
$userInfo['userEmail'],
Strings::strPad(_('Purchase confirmation from'),1,' ',STR_PAD_RIGHT) . $config->getOpt('site_name'),
$boostPurchaseConfirmMsg,
nl2br($boostPurchaseConfirmMsg));
это исключение из кода, который отправляет почту:
$mail->sendMsg($config->getOpt('site_name'),
$config->getOpt('site_email'),
$_POST['userEmail'],
$_POST['userEmail'],
Strings::strPad(_('Welcome to')) . $config->getOpt('site_name') . '!',
$registerMsg,
nl2br($registerMsg));
это функция внутри нашего объекта-обертки, которая фактически отправляет письма:
public function sendMsg($fromName, $fromEmail, $toName, $toEmail, $subject, $messageText, $messageHTML = null, $CCs = null)
{
$mail = new PHPMailer(true);
if (false === $mail) {
throw new gException('No PHPMailer object available');
}
try {
$mail->isSMTP(); // Set mailer to use SMTP
$mail->SMTPDebug = 3;
$mail->Host = $this->host; // Specify main and backup SMTP servers
$mail->Port = $this->port;
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = $this->username; // SMTP username
$mail->Password = $this->password; // SMTP password
$mail->SMTPSecure = 'tls';
$mail->From = $fromEmail;
$mail->FromName = $fromName;
$mail->addAddress($toEmail, $toName); // Add a recipient
$mail->addReplyTo($fromEmail, $fromName);
if (null !== $CCs) {
if (is_array($CCs)) {
foreach ($CCs AS $cc) {
$mail->addBCC($cc);
}
} else {
$mail->addBCC($CCs);
}
}
$mail->WordWrap = 50;
$mail->isHTML(true);
if (strlen($messageText) < 1) {
$messageText = $messageHTML;
}
if (strlen($messageHTML) < 1) {
$messageHTML = $messageText;
}
$mail->Subject = $subject;
$mail->Body = nl2br($messageHTML);
$mail->AltBody = strip_tags($messageText);
return $mail->send();
} catch (PHPMailerException $e) {
throw new gException('PHPMailer exception message : ' . $e->errorMessage());
}
}
, пожалуйста, помогите . я уже пробовал установить mock smtp service на Travis, но это не имеет значения. я рассмотрел, если мы используем правильный порт. Я сделал все, что предлагает phpmailer wiki, чтобы попытаться устранить неполадки.
Я повторяю, тесты проходят локально, поэтому все работает. Трэвис держит меня в заложниках.
UPDATE
это может показаться вводящим в заблуждение, решение, как выясняется, состояло в том, чтобы не проверять успех PHPMailer при отправке почты. у нас было соглашение, что мы не будем информировать пользователя о том, что письма не отправляются, поскольку они являются только информативными, вместо этого мы будем регистрировать исключения для дальнейшего анализа.
не проверять успешность почты на travis , это не удастся. travis не разрешает исходящий SMTP-трафик.
используйте стратегии, предложенные вики по устранению неполадок PHPMailer.
спасибо @ Syncro