[Messenger] Don't prevent dispatch out of another bus
authorMaxime Steinhausser <maxime.steinhausser@elao.com>
Fri, 28 Aug 2020 10:11:33 +0000 (12:11 +0200)
committerFabien Potencier <fabien@potencier.org>
Thu, 10 Sep 2020 17:13:35 +0000 (19:13 +0200)
src/Symfony/Component/Messenger/CHANGELOG.md
src/Symfony/Component/Messenger/Middleware/DispatchAfterCurrentBusMiddleware.php
src/Symfony/Component/Messenger/Tests/Middleware/DispatchAfterCurrentBusMiddlewareTest.php

index 3994759..8a0e0b1 100644 (file)
@@ -6,6 +6,7 @@ CHANGELOG
 
 * Added `FlattenExceptionNormalizer` to give more information about the exception on Messenger background processes. The `FlattenExceptionNormalizer` has a higher priority than `ProblemNormalizer` and it is only used when the Messenger serialization context is set.
 * Added factory methods to `DelayStamp`.
+* Removed the exception when dispatching a message with a `DispatchAfterCurrentBusStamp` and not in a context of another dispatch call
 
 5.1.0
 -----
index 05ee86f..a088140 100644 (file)
@@ -44,12 +44,13 @@ class DispatchAfterCurrentBusMiddleware implements MiddlewareInterface
     public function handle(Envelope $envelope, StackInterface $stack): Envelope
     {
         if (null !== $envelope->last(DispatchAfterCurrentBusStamp::class)) {
-            if (!$this->isRootDispatchCallRunning) {
-                throw new \LogicException(sprintf('You can only use a "%s" stamp in the context of a message handler.', DispatchAfterCurrentBusStamp::class));
+            if ($this->isRootDispatchCallRunning) {
+                $this->queue[] = new QueuedEnvelope($envelope, $stack);
+
+                return $envelope;
             }
-            $this->queue[] = new QueuedEnvelope($envelope, $stack);
 
-            return $envelope;
+            $envelope = $envelope->withoutAll(DispatchAfterCurrentBusStamp::class);
         }
 
         if ($this->isRootDispatchCallRunning) {
index b2407f1..c6a1a34 100644 (file)
@@ -256,6 +256,28 @@ class DispatchAfterCurrentBusMiddlewareTest extends TestCase
         $messageBus->dispatch($message);
     }
 
+    public function testDispatchOutOfAnotherHandlerDispatchesAndRemoveStamp()
+    {
+        $event = new DummyEvent('First event');
+
+        $middleware = new DispatchAfterCurrentBusMiddleware();
+        $handlingMiddleware = $this->createMock(MiddlewareInterface::class);
+
+        $handlingMiddleware
+            ->method('handle')
+            ->with($this->expectHandledMessage($event))
+            ->will($this->willHandleMessage());
+
+        $eventBus = new MessageBus([
+            $middleware,
+            $handlingMiddleware,
+        ]);
+
+        $enveloppe = $eventBus->dispatch($event, [new DispatchAfterCurrentBusStamp()]);
+
+        self::assertNull($enveloppe->last(DispatchAfterCurrentBusStamp::class));
+    }
+
     private function expectHandledMessage($message): Callback
     {
         return $this->callback(function (Envelope $envelope) use ($message) {