From 842998e3d2ad10d9c526912869fe1b67c01f6aa5 Mon Sep 17 00:00:00 2001
From: Ted Bowman <41201-tedbow@users.noreply.drupalcode.org>
Date: Fri, 27 Jan 2023 21:12:56 +0000
Subject: [PATCH] Issue #3336247 by tedbow, yash.rode, Wim Leers: Throw an
 exception if stopPropagation() called for `PreOperationStageEvent` and no
 error has been added

---
 .../src/Event/PreOperationStageEvent.php          | 11 +++++++++++
 .../tests/src/Kernel/StageEventsTest.php          | 15 +++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/package_manager/src/Event/PreOperationStageEvent.php b/package_manager/src/Event/PreOperationStageEvent.php
index 64f975fb09..c493c2a44a 100644
--- a/package_manager/src/Event/PreOperationStageEvent.php
+++ b/package_manager/src/Event/PreOperationStageEvent.php
@@ -6,6 +6,7 @@ namespace Drupal\package_manager\Event;
 
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\package_manager\ValidationResult;
+use Drupal\system\SystemManager;
 
 /**
  * Base class for events dispatched before a stage life cycle operation.
@@ -63,4 +64,14 @@ abstract class PreOperationStageEvent extends StageEvent {
     $this->results[] = ValidationResult::createErrorFromThrowable($throwable, $summary);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function stopPropagation(): void {
+    if (empty($this->getResults(SystemManager::REQUIREMENT_ERROR))) {
+      $this->addErrorFromThrowable(new \LogicException('Event propagation stopped without any errors added to the event. This bypasses the package_manager validation system.'));
+    }
+    parent::stopPropagation();
+  }
+
 }
diff --git a/package_manager/tests/src/Kernel/StageEventsTest.php b/package_manager/tests/src/Kernel/StageEventsTest.php
index 06161dccd4..21abdab105 100644
--- a/package_manager/tests/src/Kernel/StageEventsTest.php
+++ b/package_manager/tests/src/Kernel/StageEventsTest.php
@@ -194,4 +194,19 @@ class StageEventsTest extends PackageManagerKernelTestBase implements EventSubsc
     (new PreApplyEvent($stage))->excludePath('/junk/drawer');
   }
 
+  /**
+   * Tests exception is thrown if error is not added before stopPropagation().
+   */
+  public function testExceptionIfNoErrorBeforeStopPropagation(): void {
+    $listener = function (PreCreateEvent $event): void {
+      $event->stopPropagation();
+    };
+    $this->addEventTestListener($listener, PreCreateEvent::class);
+
+    $this->expectException(TestStageValidationException::class);
+    $this->expectExceptionMessage('Event propagation stopped without any errors added to the event. This bypasses the package_manager validation system.');
+    $stage = $this->createStage();
+    $stage->create();
+  }
+
 }
-- 
GitLab