Problem/Motivation
I found this when saving a node with an invalid uri in a link field:
The website encountered an unexpected error. Try again later.
Drupal\Core\Entity\EntityStorageException: The URI 'www.example.com' is invalid. You must use a valid URI scheme. in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 817 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Drupal\link\Plugin\Field\FieldType\LinkItem->getUrl() (Line: 166)
Drupal\link\Plugin\Field\FieldType\LinkItem->isExternal() (Line: 25)
Drupal\entity_usage\Plugin\EntityUsage\Track\Link->getTargetEntities() (Line: 175)
Drupal\entity_usage\EntityUsageTrackBase->trackOnEntityCreation() (Line: 202)
Drupal\entity_usage\EntityUsageTrackBase->trackOnEntityUpdate() (Line: 101)
Drupal\entity_usage\EntityUpdateManager->trackUpdateOnEdition() (Line: 44)
entity_usage_entity_update()
Steps to reproduce
I'm dealing with legacy migrated data so normally the field validation would stop the data from getting into this state.
However for a bit more resilience a try catch could be added.
Proposed resolution
Add try / catch / log approach around calls to \Drupal\entity_usage\EntityUsageTrackInterface::getTargetEntities() so that any exceptions arising for entity track plugins are logged and do not prevent saving.
Comments
Comment #2
dahousecat commentedComment #3
dahousecat commentedHuh, actually the exception was thrown via trackUpdateOnEdition, not trackUpdateOnDeletion.
Updated patch to try catch that method too.
Comment #4
alexpottNice find... the problem here is that \Drupal\entity_usage\Plugin\EntityUsage\Track\Link::getTargetEntities should not throw the exception. We should put the. try catch in there. Also I don't think we should be logging here either. I think we should just return an empty array and move on. That means other fields with entities will still be tracked for this entity.
Comment #5
alexpottOr perhaps even better would be to put the try catch inside field loop in \Drupal\entity_usage\EntityUsageTrackBase::trackOnEntityUpdate() and \Drupal\entity_usage\EntityUsageTrackBase::trackOnEntityCreation()... it's tricky - that'd be more robust but potentially more likely to catch something you would want to log - so if we do that we should log as well.
Comment #6
alexpottI pushed an MR that starts on #5 - just need to add logging service in a BC compat way...
Comment #7
alexpottAdded logging...
Comment #9
alexpottComment #10
alexpottCould do with adding an automated test here.
Comment #11
alexpottI think this is ready now. We log any exceptions thrown by track and have test coverage that the exceptions are logged.
Comment #12
alexpottComment #15
marcoscanoThanks for jumping in and for the generic solution in the base class! 👍