jolicode / elastically

🔍 JoliCode's Elastica wrapper to bootstrap Elasticsearch PHP integrations
248 stars 37 forks source link

Symfony\Component\ErrorHandler\Exception\FlattenException during scheduleIndex() requests #60

Closed Daisuke-sama closed 3 years ago

Daisuke-sama commented 3 years ago

Hi, I can't figure it out. Please, help. I even started to with clean ElasticaBundle.

[TypeError]
Argument 1 passed to Symfony\Component\ErrorHandler\Exception\FlattenException::setPrevious() must be an instance of Symfony\Component\ErrorHandler\Exception\FlattenException, nul
l given, called in /Users/user/projects/74/doko-deep-search/app/vendor/symfony/property-access/PropertyAccessor.php on line 541

Exception trace: at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/error-handler/Exception/FlattenException.php:239 Symfony\Component\ErrorHandler\Exception\FlattenException->setPrevious() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/property-access/PropertyAccessor.php:541 Symfony\Component\PropertyAccess\PropertyAccessor->writeProperty() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/property-access/PropertyAccessor.php:138 Symfony\Component\PropertyAccess\PropertyAccessor->setValue() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php:163 Symfony\Component\Serializer\Normalizer\ObjectNormalizer->setAttributeValue() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php:336 Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->denormalize() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Serializer.php:208 Symfony\Component\Serializer\Serializer->denormalize() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php:471 Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->validateAndDenormalize() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php:506 Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->denormalizeParameter() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php:385 Symfony\Component\Serializer\Normalizer\AbstractNormalizer->instantiateObject() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php:233 Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->instantiateObject() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php:311 Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->denormalize() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Serializer.php:208 Symfony\Component\Serializer\Serializer->denormalize() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Normalizer/ArrayDenormalizer.php:62 Symfony\Component\Serializer\Normalizer\ArrayDenormalizer->denormalize() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Serializer.php:208 Symfony\Component\Serializer\Serializer->denormalize() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/serializer/Serializer.php:144 Symfony\Component\Serializer\Serializer->deserialize() at /Users/user/projects/74/doko-deep-search/app/src/Util/IndexJsonSerializer.php:53 App\Util\IndexJsonSerializer->deserialize() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/messenger/Transport/Serialization/Serializer.php:120 Symfony\Component\Messenger\Transport\Serialization\Serializer->decodeStamps() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/messenger/Transport/Serialization/Serializer.php:73 Symfony\Component\Messenger\Transport\Serialization\Serializer->decode() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/doctrine-messenger/Transport/DoctrineReceiver.php:160 Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineReceiver->createEnvelopeFromData() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/doctrine-messenger/Transport/DoctrineReceiver.php:70 Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineReceiver->get() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/doctrine-messenger/Transport/DoctrineTransport.php:45 Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransport->get() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/messenger/Worker.php:72 Symfony\Component\Messenger\Worker->run() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/messenger/Command/ConsumeMessagesCommand.php:198 Symfony\Component\Messenger\Command\ConsumeMessagesCommand->execute() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/console/Command/Command.php:256 Symfony\Component\Console\Command\Command->run() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/console/Application.php:989 Symfony\Component\Console\Application->doRunCommand() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/framework-bundle/Console/Application.php:96 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/console/Application.php:290 Symfony\Component\Console\Application->doRun() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/framework-bundle/Console/Application.php:82 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /Users/user/projects/74/doko-deep-search/app/vendor/symfony/console/Application.php:166 Symfony\Component\Console\Application->run() at /Users/user/projects/74/doko-deep-search/app/bin/console:43

damienalexandre commented 3 years ago

Hi,

could you provide some more information about the issue? This is related to the Symfony Serializer.

You are used Doctrine as a Messenger transport, am I right? Then a class of yours is called: src/Util/IndexJsonSerializer.php, what is it?

Daisuke-sama commented 3 years ago

Oh, yes, My service is a proxy between external data-house and elasticsearch server. So, I don't use doctrine for ingesting the data. The flow is when the data request comes to the indexation it is transformed to the elastic search maps, then goes to the messenger for further indexation and logging - here is exactly the place where I call schedule() functions.

My IndexJsonSerializer created just for having camelCase name converter added to the default symfony serializer.

damienalexandre commented 3 years ago

Without seeing some code I'm not able to help sorry.

One possibility could be that your custom IndexJsonSerializer mess with the Serializer used inside the Messenger component of Symfony. Each "Message" is serialized in the transport (Doctrine here but it does not matter). When a Message is received, the denormalizer is called, and from what I can see, that's where you have a issue: Symfony is not able to rebuild the Message DTO properly.

There is also probably a bug in the Error Handler too that prevent you from seeing the real issue.

https://github.com/symfony/symfony/blob/20e5441eb893f9da932b529dcd9f8e254bbf0cc5/src/Symfony/Component/PropertyAccess/PropertyAccessor.php#L541 throw the exception.

May I suggest you remove your custom converter to test the behavior again?

Daisuke-sama commented 3 years ago

Well, it appears to hard to describe. Currently, I see " #message: "Return value of JoliCode\Elastically\Client::getSerializer() must implement interface Symfony\Component\Serializer\SerializerInterface, string returned" if I set elastically_serializer: App\Util\JsonIndexSerializer

...
use Symfony\Component\Serializer\SerializerInterface;

class IndexJsonSerializer implements SerializerInterface
{
    private Serializer $serializer;

    public function __construct()
    {
        $normalizers = [
            new PropertyNormalizer(),
            new ArrayDenormalizer(),
            new DateTimeNormalizer(),
            new ObjectNormalizer(
                new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())),
                new CamelCaseToSnakeCaseNameConverter(),
                null,
                new PhpDocExtractor()
            ),
        ];

        $encoders = [
            new JsonEncoder()
        ];

        $this->serializer = new Serializer($normalizers, $encoders);
    }

    public function serialize($data, string $format, array $context = []): string
    {
        return $this->serializer->serialize($data, 'json', $context);
    }

    public function deserialize($data, string $type, string $format, array $context = [])
    {
        return $this->serializer->deserialize($data, $type, 'json', $context);
    }
}
damienalexandre commented 3 years ago

But this has nothing to do with your original error?

To fix this may I suggest you had an alias on your custom service and reference it with the @ marker?

App\Util\JsonIndexSerializer:
    alias: my_serializer

elastically:
    elastically_serializer: @my_serializer
Daisuke-sama commented 3 years ago

I read your latest article and decide to use the library by the way. Could you correct me if I have created the config wrong in config/packages/elastically.yaml and wrote the next

services:

  JoliCode\Elastically\Transport\HttpClientTransport: ~
  JoliCode\Elastically\Messenger\IndexationRequestHandler: ~
  JoliCode\Elastically\Client:
    arguments:
      $config:
        host: '%env(ELASTICSEARCH_HOST)%'
        port: '%env(ELASTICSEARCH_PORT)%'
        transport: '@JoliCode\Elastically\Transport\HttpClientTransport'
        elastically_mappings_directory: '%kernel.project_dir%/config/elastically_maps'
        elastically_index_class_mapping:
          medicine: App\Model\MedicineModel
        elastically_serializer: '@app_index_serializer'
        elastically_bulk_size: 10
      $logger: '@logger'

  JoliCode\Elastically\Messenger\DocumentExchangerInterface:
    alias: App\Elasticsearch\MedicineDocumentExchanger

Can I remove that and just keep the elastically.yaml with related config not. directly bound to the $config variable?

Daisuke-sama commented 3 years ago

Hello, Alexandre, I think I am closing this ticket because I found the workaround - re-create my models so it doesn't require a new serializer. Need to move forward. Appreciate your help and the development!!