diff --git a/src/Entity/Aggregator.php b/src/Entity/Aggregator.php index d0f156d9..7772c343 100644 --- a/src/Entity/Aggregator.php +++ b/src/Entity/Aggregator.php @@ -43,6 +43,11 @@ public function __construct($entity, array $entityIdentifierValues) $this->objectID = get_class($this->entity).'::'.reset($entityIdentifierValues); } + public function getObjectID() + { + return $this->objectID; + } + /** * Returns the entities class names that should be aggregated. * diff --git a/src/IndexManager.php b/src/IndexManager.php index 15bd3300..f398de6e 100644 --- a/src/IndexManager.php +++ b/src/IndexManager.php @@ -78,9 +78,15 @@ public function index($entities, ObjectManager $objectManager) $this->remove($entitiesToBeRemoved, $objectManager); } - return $this->forEachChunk($objectManager, $entitiesToBeIndexed, function ($chunk) { - return $this->engine->update($chunk); - }); + try { + return $this->forEachChunk($objectManager, $entitiesToBeIndexed, function ($chunk) { + return $this->engine->update($chunk); + }); + } catch (\Exception $e) { + $message = $this->formatIndexingException($e, $entitiesToBeIndexed); + + throw new \Exception($message); + } } public function remove($entities, ObjectManager $objectManager) @@ -335,4 +341,35 @@ private function removePrefixFromIndexName($indexName) { return preg_replace('/^'.preg_quote($this->configuration['prefix'], '/').'/', '', $indexName); } + + private function formatIndexingException($exception, $entitiesToBeIndexed) + { + // Retrieve the objectID if returned by the API + preg_match('/objectID=(.*?)\sis\stoo\sbig/', $exception->getMessage(), $matches); + + if (count($matches) === 0) { + return $exception->getMessage(); + } + + $objectId = $matches[1]; + $entityId = null; + $faultyEntity = null; + $detailedInfos = ''; + foreach ($entitiesToBeIndexed as $entityToBeIndexed) { + if (get_parent_class($entityToBeIndexed) === Aggregator::class) { + $entityId = $entityToBeIndexed->getObjectID(); + } else { + $entityId = (string) $entityToBeIndexed->getId(); + } + + if ($entityId === $objectId) { + $faultyEntity = $this->normalizer->serialize($entityToBeIndexed, 'json'); + $truncatedEntity = strlen($faultyEntity) > 300 ? + substr($faultyEntity, 0, 300) . '...' : $faultyEntity; + $detailedInfos = "\nObject overview: " . $truncatedEntity; + } + } + + return $exception->getMessage() . $detailedInfos; + } } diff --git a/tests/TestCase/IndexManagerTest.php b/tests/TestCase/IndexManagerTest.php index 08231b63..3e282dd8 100644 --- a/tests/TestCase/IndexManagerTest.php +++ b/tests/TestCase/IndexManagerTest.php @@ -169,4 +169,45 @@ public function testIndexIfCondition() // The content aggregator expects 3 ( not 4, because of the index_if condition ). $this->assertEquals(3, $this->indexManager->count('', ContentAggregator::class)); } + + public function testIndexOversizedEntityData() + { + $this->expectException('Exception'); + $this->expectExceptionMessageRegExp('/objectID=10/'); + $this->expectExceptionMessageRegExp('/Object overview/'); + $om = $this->get('doctrine')->getManager(); + + $posts = []; + for ($i = 0; $i < 3; $i++) { + $posts[] = $this->createPost($i); + } + + $post = $this->createPost(10); + $post->setTitle(str_repeat('Foo',10000)); + $posts[] = $post; + + $this->indexManager->index($posts, $om); + } + + /** + * @expectedException \Exception + */ + public function testIndexOversizedAggregatorData() + { + $this->expectException('Exception'); + $this->expectExceptionMessageRegExp('/objectID=Algolia\SearchBundle\TestApp\Entity\Image::1/'); + $this->expectExceptionMessageRegExp('/Object overview/'); + $om = $this->get('doctrine')->getManager(); + + $posts = []; + for ($i = 0; $i < 3; $i++) { + $posts[] = $this->createPost($i); + } + + $comment = $this->createComment(1); + $image = $this->createImage(1); + $image->setUrl(str_repeat('Foo',10000)); + + $this->indexManager->index(array_merge($posts, [$comment, $image]), $om); + } }