diff --git a/core/lib/Drupal/Core/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Field/FieldItemInterface.php index aee45492f28711716f6638b33d5f6896468b32cb..d6ef1557e689b4159fc4fc9212079f3698bb56d5 100644 --- a/core/lib/Drupal/Core/Field/FieldItemInterface.php +++ b/core/lib/Drupal/Core/Field/FieldItemInterface.php @@ -84,6 +84,9 @@ public static function mainPropertyName(); * stored in SQL. Also, the possible usage is limited, as you cannot * specify another field as related, only existing SQL tables, * such as {taxonomy_term_data}. + * + * @throws \Drupal\Core\Field\FieldException + * Throws an exception if the schema is invalid. */ public static function schema(FieldStorageDefinitionInterface $field_definition); diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php index 146b9fd68e32bc151b5230bc05e1afb36efe8edd..43cd540bb2ab4a7571f5131e9608b750313f6d27 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php @@ -6,6 +6,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\ContentEntityStorageInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Component\Plugin\Exception\PluginNotFoundException; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Entity\TypedData\EntityDataDefinition; @@ -121,7 +122,16 @@ public static function mainPropertyName() { */ public static function schema(FieldStorageDefinitionInterface $field_definition) { $target_type = $field_definition->getSetting('target_type'); - $target_type_info = \Drupal::entityTypeManager()->getDefinition($target_type); + try { + $target_type_info = \Drupal::entityTypeManager()->getDefinition($target_type); + } + catch (PluginNotFoundException $e) { + throw new FieldException(sprintf("Field '%s' on entity type '%s' references a target entity type '%s' which does not exist.", + $field_definition->getName(), + $field_definition->getTargetEntityTypeId(), + $target_type + )); + } $properties = static::propertyDefinitions($field_definition)['target_id']; if ($target_type_info->entityClassImplements(FieldableEntityInterface::class) && $properties->getDataType() === 'integer') { $columns = [ diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceFieldTest.php index c3005afd879dc98936fc94c68199a406d8a03d35..9b58c8d0a6b77139591472c95b70cfc3659b39d3 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceFieldTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceFieldTest.php @@ -6,6 +6,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageException; use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\Field\FieldException; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; @@ -368,6 +369,26 @@ protected function assertUserRoleAutocreate(EntityInterface $entity, callable $s $this->assertEquals($entity->user_role->target_id, $role->id()); } + /** + * Tests exception thrown with a missing target entity type. + */ + public function testTargetEntityTypeMissing() { + // Setup a test entity type with an entity reference field to an entity type + // that doesn't exist. + $definitions = [ + 'bad_reference' => BaseFieldDefinition::create('entity_reference') + ->setSetting('target_type', 'made_up_entity_type') + ->setSetting('handler', 'default'), + ]; + $this->state->set('entity_test.additional_base_field_definitions', $definitions); + $this->entityTypeManager->clearCachedDefinitions(); + + $this->expectException(FieldException::class); + $this->expectExceptionMessage("Field 'bad_reference' on entity type 'entity_test' references a target entity type 'made_up_entity_type' which does not exist."); + + $this->installEntitySchema('entity_test'); + } + /** * Tests that the target entity is not unnecessarily loaded. */