8000 Add `NestedExceptionsInterface` interface for exceptions that hold mu… · symfony/symfony@30c69c5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 30c69c5

Browse files
committed
Add NestedExceptionsInterface interface for exceptions that hold multiple individual exceptions
1 parent 7c833ee commit 30c69c5

7 files changed

+92
-3
lines changed

UPGRADE-6.4.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ Messenger
112112
---------
113113

114114
* Deprecate `StopWorkerOnSignalsListener` in favor of using the `SignalableCommandInterface`
115+
* Deprecate `HandlerFailedException::getNestedExceptionOfClass` which is replaced by `HandlerFailedException::getWrappedExceptions`
115116

116117
MonologBridge
117118
-------------

src/Symfony/Component/Messenger/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Deprecate `StopWorkerOnSignalsListener` in favor of using the `SignalableCommandInterface`
88
* Add `HandlerDescriptor::getOptions`
9+
* Add `NestedExceptionsInterface` interface for exceptions that hold multiple individual exceptions
910

1011
6.3
1112
---

src/Symfony/Component/Messenger/Exception/DelayedMessageHandlingException.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
*
1818
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
1919
*/
20-
class DelayedMessageHandlingException extends RuntimeException
20+
class DelayedMessageHandlingException extends RuntimeException implements NestedExceptionsInterface
2121
{
22+
use NestedExceptionsTrait;
23+
2224
private array $exceptions;
2325

2426
public function __construct(array $exceptions)

src/Symfony/Component/Messenger/Exception/HandlerFailedException.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313

1414
use Symfony\Component\Messenger\Envelope;
1515

16-
class HandlerFailedException extends RuntimeException
16+
class HandlerFailedException extends RuntimeException implements NestedExceptionsInterface
1717
{
18+
use NestedExceptionsTrait;
19+
1820
private array $exceptions;
1921
private Envelope $envelope;
2022

@@ -55,6 +57,8 @@ public function getNestedExceptions(): array
5557

5658
public function getNestedExceptionOfClass(string $exceptionClassName): array
5759
{
60+
trigger_deprecation('symfony/messenger', '6.4', 'The "%s()" method is deprecated, use "%s::getWrappedExceptions" instead.', __METHOD__, self::class);
61+
5862
return array_values(
5963
array_filter(
6064
$this->exceptions,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Exception;
13+
14+
/**
15+
* Exception that holds multiple exceptions thrown by one or more handlers and/or messages.
16+
*
17+
* @author Jeroen <https://github.com/Jeroeny>
18+
*/
19+
interface NestedExceptionsInterface extends \Throwable
20+
{
21+
/**
22+
* @return \Throwable[]
23+
*/
24+
public function getWrappedExceptions(string $class = null, bool $recursive = false): array;
25+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Exception;
13+
14+
/**
15+
* @author Jeroen <https://github.com/Jeroeny>
16+
*/
17+
trait NestedExceptionsTrait
18+
{
19+
/**
20+
* @return \Throwable[]
21+
*/
22+
public function getWrappedExceptions(string $class = null, bool $recursive = false): array
23+
{
24+
return $recursive ? iterator_to_array($this->getWrappedExceptionsRecursively($class, $this->exceptions), false) : $this->exceptions;
25+
}
26+
27+
/**
28+
* @param iterable<\Throwable>
29+
*
30+
* @return \Traversable<\Throwable>
31+
*/
32+
private function getWrappedExceptionsRecursively(?string $class, iterable $exceptions): \Traversable
33+
{
34+
foreach ($exceptions as $exception) {
35+
if ($exception instanceof NestedExceptionsInterface) {
36+
yield from $this->getWrappedExceptionsRecursively($class, $exception->getWrappedExceptions());
37+
38+
return;
39+
}
40+
41+
yield $exception;
42+
}
43+
}
44+
}

src/Symfony/Component/Messenger/Tests/Exception/HandlerFailedExceptionTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Messenger\Envelope;
16+
use Symfony\Component\Messenger\Exception\DelayedMessageHandlingException;
1617
use Symfony\Component\Messenger\Exception\HandlerFailedException;
1718
use Symfony\Component\Messenger\Tests\Fixtures\MyOwnChildException;
1819
use Symfony\Component\Messenger\Tests\Fixtures\MyOwnException;
@@ -32,7 +33,7 @@ public function __construct()
3233
};
3334

3435
$handlerException = new HandlerFailedException($envelope, [$exception]);
35-
$originalException = $handlerException->getNestedExceptions()[0];
36+
$originalException = $handlerException->getWrappedExceptions()[0];
3637

3738
$this->assertIsInt($handlerException->getCode(), 'Exception codes must converts to int');
3839
$this->assertSame(0, $handlerException->getCode(), 'String code (HY000) converted to int must be 0');
@@ -66,4 +67,15 @@ public function testThatNestedExceptionClassAreNotFoundIfNotPresent()
6667
$handlerException = new HandlerFailedException($envelope, [$exception]);
6768
$this->assertCount(0, $handlerException->getNestedExceptionOfClass(MyOwnException::class));
6869
}
70+
71+
public function testThatNestedExceptionsRecursive()
72+
{
73+
$envelope = new Envelope(new \stdClass());
74+
$exception1 = new \LogicException();
75+
$exception2 = new MyOwnException('second');
76+
$exception3 = new MyOwnException('third');
77+
78+
$handlerException = new HandlerFailedException($envelope, [$exception1, $exception2, new DelayedMessageHandlingException([$exception3])]);
79+
$this->assertSame([$exception1, $exception2, $exception3], $handlerException->getWrappedExceptions(recursive: true));
80+
}
6981
}

0 commit comments

Comments
 (0)
0