Skip to content

Commit

Permalink
[Mailer] Include all transports' debug messages in RoundRobin transpo…
Browse files Browse the repository at this point in the history
…rt exception
  • Loading branch information
mithredate authored and nicolas-grekas committed Dec 14, 2022
1 parent 501ac1c commit fd81641
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
48 changes: 44 additions & 4 deletions Tests/Transport/RoundRobinTransportTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use PHPUnit\Framework\TestCase;
use Symfony\Component\Mailer\Exception\TransportException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\Transport\RoundRobinTransport;
use Symfony\Component\Mailer\Transport\TransportInterface;
use Symfony\Component\Mime\RawMessage;
Expand Down Expand Up @@ -60,10 +61,21 @@ public function testSendAllDead()
$t2 = $this->createMock(TransportInterface::class);
$t2->expects($this->once())->method('send')->will($this->throwException(new TransportException()));
$t = new RoundRobinTransport([$t1, $t2]);
$this->expectException(TransportException::class);
$this->expectExceptionMessage('All transports failed.');
$t->send(new RawMessage(''));
$this->assertTransports($t, 1, [$t1, $t2]);
$p = new \ReflectionProperty($t, 'cursor');
$p->setAccessible(true);
$p->setValue($t, 0);

try {
$t->send(new RawMessage(''));
} catch (\Exception $e) {
$this->assertInstanceOf(TransportException::class, $e);
$this->assertStringContainsString('All transports failed.', $e->getMessage());
$this->assertTransports($t, 0, [$t1, $t2]);

return;
}

$this->fail('The expected exception was not thrown.');
}

public function testSendOneDead()
Expand Down Expand Up @@ -127,6 +139,34 @@ public function testSendOneDeadAndRecoveryWithinRetryPeriod()
$this->assertTransports($t, 1, []);
}

public function testFailureDebugInformation()
{
$t1 = $this->createMock(TransportInterface::class);
$e1 = new TransportException();
$e1->appendDebug('Debug message 1');
$t1->expects($this->once())->method('send')->will($this->throwException($e1));
$t1->expects($this->once())->method('__toString')->willReturn('t1');

$t2 = $this->createMock(TransportInterface::class);
$e2 = new TransportException();
$e2->appendDebug('Debug message 2');
$t2->expects($this->once())->method('send')->will($this->throwException($e2));
$t2->expects($this->once())->method('__toString')->willReturn('t2');

$t = new RoundRobinTransport([$t1, $t2]);

try {
$t->send(new RawMessage(''));
} catch (TransportExceptionInterface $e) {
$this->assertStringContainsString('Transport "t1": Debug message 1', $e->getDebug());
$this->assertStringContainsString('Transport "t2": Debug message 2', $e->getDebug());

return;
}

$this->fail('Expected exception was not thrown!');
}

private function assertTransports(RoundRobinTransport $transport, int $cursor, array $deadTransports)
{
$p = new \ReflectionProperty($transport, 'cursor');
Expand Down
6 changes: 5 additions & 1 deletion Transport/RoundRobinTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,19 @@ public function __construct(array $transports, int $retryPeriod = 60)

public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage
{
$exception = null;

while ($transport = $this->getNextTransport()) {
try {
return $transport->send($message, $envelope);
} catch (TransportExceptionInterface $e) {
$exception = $exception ?? new TransportException('All transports failed.');
$exception->appendDebug(sprintf("Transport \"%s\": %s\n", $transport, $e->getDebug()));
$this->deadTransports[$transport] = microtime(true);
}
}

throw new TransportException('All transports failed.');
throw $exception ?? new TransportException('No transports found.');
}

public function __toString(): string
Expand Down

0 comments on commit fd81641

Please sign in to comment.