Problem/Motivation
To put it bluntly and in short, this module is unusable with
Drupal Commerce →
and likely other modules/configurations, see also
#3192077: SqlContentEntityStorageException →
.
I'm fairly certain there are other modules as well as custom entities in the wild that would conflict with this module, in particular because every entity insert and update tries to serialize that entity but not every content entity is guaranteed to be serializable.
Steps to reproduce
Install
Commerce Kickstart demo →
Install content_sync
Try to add a product to your cart and continue through the checkout process
Expected result: Checkout works as expected
Actual result: Fatal PHP errors as content_sync encounters objects it's not able to serialize. Errors (including relevant part of call stack):
TypeError: Drupal\serialization\Normalizer\TypedDataNormalizer::normalize(): Return value must be of type ArrayObject|array|string|int|float|bool|null, Drupal\commerce_order\Adjustment returned in Drupal\serialization\Normalizer\TypedDataNormalizer->normalize() (line 22 of core/modules/serialization/src/Normalizer/TypedDataNormalizer.php).
Symfony\Component\Serializer\Serializer->normalize() (Line: 37)
Drupal\serialization\Normalizer\ComplexDataNormalizer->normalize() (Line: 152)
Symfony\Component\Serializer\Serializer->normalize() (Line: 24)
Drupal\serialization\Normalizer\ListNormalizer->normalize() (Line: 152)
Symfony\Component\Serializer\Serializer->normalize() (Line: 25)
Drupal\serialization\Normalizer\ContentEntityNormalizer->normalize() (Line: 92)
Drupal\content_sync\Normalizer\ContentEntityNormalizer->normalize() (Line: 152)
Symfony\Component\Serializer\Serializer->normalize() (Line: 131)
Symfony\Component\Serializer\Serializer->serialize() (Line: 35)
Drupal\content_sync\Exporter\ContentExporter->exportEntity() (Line: 218)
content_sync_entity_update()
TypeError: Drupal\serialization\Normalizer\TypedDataNormalizer::normalize(): Return value must be of type ArrayObject|array|string|int|float|bool|null, Drupal\commerce_order\Adjustment returned in Drupal\serialization\Normalizer\TypedDataNormalizer->normalize() (line 22 of core/modules/serialization/src/Normalizer/TypedDataNormalizer.php).
Symfony\Component\Serializer\Serializer->normalize() (Line: 37)
Drupal\serialization\Normalizer\ComplexDataNormalizer->normalize() (Line: 152)
Symfony\Component\Serializer\Serializer->normalize() (Line: 24)
Drupal\serialization\Normalizer\ListNormalizer->normalize() (Line: 152)
Symfony\Component\Serializer\Serializer->normalize() (Line: 25)
Drupal\serialization\Normalizer\ContentEntityNormalizer->normalize() (Line: 92)
Drupal\content_sync\Normalizer\ContentEntityNormalizer->normalize() (Line: 152)
Symfony\Component\Serializer\Serializer->normalize() (Line: 131)
Symfony\Component\Serializer\Serializer->serialize() (Line: 35)
Drupal\content_sync\Exporter\ContentExporter->exportEntity() (Line: 218)
content_sync_entity_update()
Proposed resolution
Wrap the actual serialization in a try/catch, and log a warning if the entity is not able to be serialized. This way the functionality of the site is not impaired, and an admin can still track down the warnings logs and optionally troubleshoot.
These failures would be mitigated if there was an ability to exclude entity types, but regardless of that I think we shouldn't fail to catch a PHP fatal error in this scenario.
Remaining tasks
Create issue fork and MR
Review and test
User interface changes
In the single export UI there will be an error displayed if the entity is not able to be serialized for export.
Others TBD.
API changes
\Drupal\content_sync\Exporter\ContentExporterInterface::exportEntity()
will be revised to return a string (current documented behaviour) or NULL if the entity cannot be serialized.
Data model changes
n/a