From a6477d590444013b45a8545c4f1155c2b571f7d4 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Tue, 26 Nov 2019 09:04:27 +0000
Subject: [PATCH] Issue #3095895 by amateescu, alexpott:
 FieldTypePluginManager::getPluginClass() should throw an exception when
 called for a field type that doesn't exist

---
 core/lib/Drupal/Core/Field/FieldConfigStorageBase.php    | 9 ++++++---
 core/lib/Drupal/Core/Field/FieldTypePluginManager.php    | 3 +--
 .../Core/Field/FieldTypePluginManagerInterface.php       | 3 +++
 core/modules/field/src/FieldStorageConfigStorage.php     | 9 ++++++---
 .../KernelTests/Core/Field/FieldMissingTypeTest.php      | 5 +++--
 5 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/core/lib/Drupal/Core/Field/FieldConfigStorageBase.php b/core/lib/Drupal/Core/Field/FieldConfigStorageBase.php
index 29e610789665..e99053de1947 100644
--- a/core/lib/Drupal/Core/Field/FieldConfigStorageBase.php
+++ b/core/lib/Drupal/Core/Field/FieldConfigStorageBase.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Field;
 
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\Core\Config\Entity\ConfigEntityStorage;
 use Drupal\Core\Entity\EntityInterface;
 
@@ -22,10 +23,12 @@ abstract class FieldConfigStorageBase extends ConfigEntityStorage {
    */
   protected function mapFromStorageRecords(array $records) {
     foreach ($records as $id => &$record) {
-      $class = $this->fieldTypeManager->getPluginClass($record['field_type']);
-      if (empty($class)) {
+      try {
+        $class = $this->fieldTypeManager->getPluginClass($record['field_type']);
+      }
+      catch (PluginNotFoundException $e) {
         $config_id = $this->getPrefix() . $id;
-        throw new \RuntimeException("Unable to determine class for field type '{$record['field_type']}' found in the '$config_id' configuration");
+        throw new PluginNotFoundException($record['field_type'], "Unable to determine class for field type '{$record['field_type']}' found in the '$config_id' configuration", $e->getCode(), $e);
       }
       $record['settings'] = $class::fieldSettingsFromConfigData($record['settings']);
     }
diff --git a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
index 565fa4e6f749..39560ad13c6e 100644
--- a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
+++ b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
@@ -167,8 +167,7 @@ public function getPreconfiguredOptions($field_type) {
    * {@inheritdoc}
    */
   public function getPluginClass($type) {
-    $plugin_definition = $this->getDefinition($type, FALSE);
-    return $plugin_definition['class'];
+    return $this->getDefinition($type)['class'];
   }
 
 }
diff --git a/core/lib/Drupal/Core/Field/FieldTypePluginManagerInterface.php b/core/lib/Drupal/Core/Field/FieldTypePluginManagerInterface.php
index d937aabd446d..dd5e9390ae4c 100644
--- a/core/lib/Drupal/Core/Field/FieldTypePluginManagerInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldTypePluginManagerInterface.php
@@ -112,6 +112,9 @@ public function getPreconfiguredOptions($field_type);
    *
    * @return string
    *   Field type plugin class name.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   *   Thrown if the field type plugin name is invalid.
    */
   public function getPluginClass($type);
 
diff --git a/core/modules/field/src/FieldStorageConfigStorage.php b/core/modules/field/src/FieldStorageConfigStorage.php
index 6bd22c80fccf..c3b9445a48aa 100644
--- a/core/modules/field/src/FieldStorageConfigStorage.php
+++ b/core/modules/field/src/FieldStorageConfigStorage.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\field;
 
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Cache\MemoryCache\MemoryCacheInterface;
 use Drupal\Core\Config\Entity\ConfigEntityStorage;
@@ -158,10 +159,12 @@ public function loadByProperties(array $conditions = []) {
    */
   protected function mapFromStorageRecords(array $records) {
     foreach ($records as $id => &$record) {
-      $class = $this->fieldTypeManager->getPluginClass($record['type']);
-      if (empty($class)) {
+      try {
+        $class = $this->fieldTypeManager->getPluginClass($record['type']);
+      }
+      catch (PluginNotFoundException $e) {
         $config_id = $this->getPrefix() . $id;
-        throw new \RuntimeException("Unable to determine class for field type '{$record['type']}' found in the '$config_id' configuration");
+        throw new PluginNotFoundException($record['type'], "Unable to determine class for field type '{$record['type']}' found in the '$config_id' configuration", $e->getCode(), $e);
       }
       $record['settings'] = $class::storageSettingsFromConfigData($record['settings']);
     }
diff --git a/core/tests/Drupal/KernelTests/Core/Field/FieldMissingTypeTest.php b/core/tests/Drupal/KernelTests/Core/Field/FieldMissingTypeTest.php
index ecaa729821e3..6a230f5f0de6 100644
--- a/core/tests/Drupal/KernelTests/Core/Field/FieldMissingTypeTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Field/FieldMissingTypeTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\KernelTests\Core\Field;
 
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\entity_test\Entity\EntityTestMulRev;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -60,7 +61,7 @@ protected function setUp() {
    * @see \Drupal\field\FieldStorageConfigStorage::mapFromStorageRecords()
    */
   public function testFieldStorageMissingType() {
-    $this->expectException(\RuntimeException::class);
+    $this->expectException(PluginNotFoundException::class);
     $this->expectExceptionMessage("Unable to determine class for field type 'foo_field_storage' found in the 'field.storage.entity_test_mulrev.{$this->fieldName}' configuration");
     $entity = EntityTestMulRev::create([
       'name' => $this->randomString(),
@@ -80,7 +81,7 @@ public function testFieldStorageMissingType() {
    * @see \Drupal\field\FieldConfigStorageBase::mapFromStorageRecords()
    */
   public function testFieldMissingType() {
-    $this->expectException(\RuntimeException::class);
+    $this->expectException(PluginNotFoundException::class);
     $this->expectExceptionMessage("Unable to determine class for field type 'foo_field' found in the 'field.field.entity_test_mulrev.entity_test_mulrev.{$this->fieldName}' configuration");
     $entity = EntityTestMulRev::create([
       'name' => $this->randomString(),
-- 
GitLab