diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml
index 04823bce0ebeb..0bcc3f7126348 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml
@@ -29,6 +29,7 @@
+
diff --git a/src/Symfony/Component/Messenger/CHANGELOG.md b/src/Symfony/Component/Messenger/CHANGELOG.md
index 2abdada660a86..74fd23873f3da 100644
--- a/src/Symfony/Component/Messenger/CHANGELOG.md
+++ b/src/Symfony/Component/Messenger/CHANGELOG.md
@@ -19,6 +19,7 @@ CHANGELOG
* [BC BREAK] The `EncoderInterface` and `DecoderInterface` have been replaced by a unified `Symfony\Component\Messenger\Transport\Serialization\SerializerInterface`.
* [BC BREAK] The locator passed to `ContainerHandlerLocator` should not prefix its keys by "handler." anymore
* [BC BREAK] The `AbstractHandlerLocator::getHandler()` method uses `?callable` as return type
+ * Added a `EnforceNullResultMiddleware` middleware
4.1.0
-----
diff --git a/src/Symfony/Component/Messenger/Exception/NonNullResultException.php b/src/Symfony/Component/Messenger/Exception/NonNullResultException.php
new file mode 100644
index 0000000000000..595a476dcd891
--- /dev/null
+++ b/src/Symfony/Component/Messenger/Exception/NonNullResultException.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Messenger\Exception;
+
+/**
+ * @author Paul Le Corre
+ */
+class NonNullResultException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/src/Symfony/Component/Messenger/Middleware/EnforceNullResultMiddleware.php b/src/Symfony/Component/Messenger/Middleware/EnforceNullResultMiddleware.php
new file mode 100755
index 0000000000000..d225741d94394
--- /dev/null
+++ b/src/Symfony/Component/Messenger/Middleware/EnforceNullResultMiddleware.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Messenger\Middleware;
+
+use Symfony\Component\Messenger\Exception\NonNullResultException;
+
+/**
+ * @author Paul Le Corre
+ */
+class EnforceNullResultMiddleware implements MiddlewareInterface
+{
+ public function handle($message, callable $next)
+ {
+ $result = $next($message);
+ if (null !== $result) {
+ throw new NonNullResultException(sprintf('Non null result for message "%s": at least one handler returned something but this is prohibited by this middleware.', \get_class($message)));
+ }
+
+ return $result;
+ }
+}
diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/EnforceNullResultMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/EnforceNullResultMiddlewareTest.php
new file mode 100644
index 0000000000000..8fb634d45fae7
--- /dev/null
+++ b/src/Symfony/Component/Messenger/Tests/Middleware/EnforceNullResultMiddlewareTest.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Messenger\Tests\Middleware;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Messenger\Middleware\EnforceNullResultMiddleware;
+use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
+
+class EnforceNullResultMiddlewareTest extends TestCase
+{
+ public function testItCallsNextMiddleware()
+ {
+ $message = new DummyMessage('Hey');
+
+ $next = $this->createPartialMock(\stdClass::class, array('__invoke'));
+ $next->expects($this->once())->method('__invoke')->with($message);
+
+ $middleware = new EnforceNullResultMiddleware();
+ $middleware->handle($message, $next);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Messenger\Exception\NonNullResultException
+ * @expectedExceptionMessage Non null result for message "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage": at least one handler returned something but this is prohibited by this middleware.
+ */
+ public function testItThrowExceptionOnNonNullResult()
+ {
+ $next = $this->createPartialMock(\stdClass::class, array('__invoke'));
+ $next->expects($this->once())->method('__invoke')->will($this->returnValue('Non null value'));
+
+ $middleware = new EnforceNullResultMiddleware();
+ $middleware->handle(new DummyMessage('Hey'), $next);
+ }
+}