geocoder-php / Geocoder

The most featured Geocoder library written in PHP.
https://geocoder-php.org
MIT License
3.94k stars 517 forks source link

Serialization of 'Closure' is not allowed #1180

Closed garak closed 1 year ago

garak commented 1 year ago

I sometimes have this error while using the geocoder google maps plugin. It seems to be caused by the Symfony cache, during the call to the handleQuery method. The method itself indeed accepts two callables as argument, so it should be expected. Any hints? TIA

jbelien commented 1 year ago

Hello @garak,

Could you provide a bit more information so we can debug this the most efficiently possible ? Could you provide a trace of the error message (or at least the file and line number) ?

Thanks.

garak commented 1 year ago

Sure, here you are

ValueError:
Serialization of 'Closure' is not allowed

  at vendor/symfony/cache/Marshaller/DefaultMarshaller.php:53
  at Symfony\Component\Cache\Marshaller\DefaultMarshaller->marshall(array('v45c0f902c35451b0850fe8071614d0753462778eb' => object(RejectedPromise)), array())
     (vendor/symfony/cache/Traits/FilesystemTrait.php:97)
  at Symfony\Component\Cache\Adapter\FilesystemAdapter->doSave(array('v45c0f902c35451b0850fe8071614d0753462778eb' => object(RejectedPromise)), 0)
     (vendor/symfony/cache/Adapter/AbstractAdapter.php:167)
  at Symfony\Component\Cache\Adapter\AbstractAdapter->commit()
     (vendor/symfony/cache/Traits/AbstractAdapterTrait.php:276)
  at Symfony\Component\Cache\Adapter\AbstractAdapter->save(object(CacheItem))
     (vendor/symfony/cache/Adapter/TraceableAdapter.php:129)
  at Symfony\Component\Cache\Adapter\TraceableAdapter->save(object(CacheItem))
     (vendor/symfony/cache/Psr16Cache.php:120)
  at Symfony\Component\Cache\Psr16Cache->set('v45c0f902c35451b0850fe8071614d0753462778eb', object(RejectedPromise), null)
     (vendor/geocoder-php/plugin/Plugin/CachePlugin.php:68)
  at Geocoder\Plugin\Plugin\CachePlugin->handleQuery(object(ReverseQuery), object(Closure), object(Closure))
     (src/redacted/geocoder/PluginProvider.php:148)
  at geocoder\PluginProvider->geocoder\{closure}(object(ReverseQuery))
     (src/redacted/geocoder/PluginProvider.php:163)
  at geocoder\PluginProvider->geocoder\{closure}(object(ReverseQuery))
     (src/redacted/geocoder/PluginProvider.php:104)
  at geocoder\PluginProvider->reverseQueryAsJson(object(ReverseQuery))
     (src/redacted/Platform/Geo/Infrastructure/Geocoder/StatefulGeocoder.php:122)
  at App\StatefulGeocoder->reverseAsJson(43.5798704, 7.1205716)
     (src/redacted/Platform/Geo/Infrastructure/Geocoder/GoogleMapsGeocoder.php:44)
  at App\GoogleMapsGeocoder->reverse(object(CoordinatePoint), 'fr', 'json', null)
     (src/redacted/Platform/Geo/Application/Geocode/ReverseQueryHandler.php:32)
  at App\ReverseQueryHandler->__invoke(object(ReverseQuery))
     (vendor/symfony/messenger/Middleware/HandleMessageMiddleware.php:97)
  at Symfony\Component\Messenger\Middleware\HandleMessageMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/SendMessageMiddleware.php:73)
  at Symfony\Component\Messenger\Middleware\SendMessageMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/FailedMessageProcessingMiddleware.php:34)
  at Symfony\Component\Messenger\Middleware\FailedMessageProcessingMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/DispatchAfterCurrentBusMiddleware.php:61)
  at Symfony\Component\Messenger\Middleware\DispatchAfterCurrentBusMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/RejectRedeliveredMessageMiddleware.php:48)
  at Symfony\Component\Messenger\Middleware\RejectRedeliveredMessageMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/AddBusNameStampMiddleware.php:37)
  at Symfony\Component\Messenger\Middleware\AddBusNameStampMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/TraceableMiddleware.php:43)
  at Symfony\Component\Messenger\Middleware\TraceableMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/MessageBus.php:77)
  at Symfony\Component\Messenger\MessageBus->dispatch(object(Envelope), array())
     (vendor/symfony/messenger/TraceableMessageBus.php:41)
  at Symfony\Component\Messenger\TraceableMessageBus->dispatch(object(Envelope), array())
     (vendor/symfony/messenger/RoutableMessageBus.php:54)
  at Symfony\Component\Messenger\RoutableMessageBus->dispatch(object(Envelope))
     (vendor/symfony/messenger/Transport/Sync/SyncTransport.php:63)
  at Symfony\Component\Messenger\Transport\Sync\SyncTransport->send(object(Envelope))
     (vendor/symfony/messenger/Middleware/SendMessageMiddleware.php:68)
  at Symfony\Component\Messenger\Middleware\SendMessageMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/FailedMessageProcessingMiddleware.php:34)
  at Symfony\Component\Messenger\Middleware\FailedMessageProcessingMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/DispatchAfterCurrentBusMiddleware.php:68)
  at Symfony\Component\Messenger\Middleware\DispatchAfterCurrentBusMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/RejectRedeliveredMessageMiddleware.php:48)
  at Symfony\Component\Messenger\Middleware\RejectRedeliveredMessageMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/AddBusNameStampMiddleware.php:37)
  at Symfony\Component\Messenger\Middleware\AddBusNameStampMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/Middleware/TraceableMiddleware.php:43)
  at Symfony\Component\Messenger\Middleware\TraceableMiddleware->handle(object(Envelope), object(TraceableStack))
     (vendor/symfony/messenger/MessageBus.php:77)
  at Symfony\Component\Messenger\MessageBus->dispatch(object(ReverseQuery), array())
     (vendor/symfony/messenger/TraceableMessageBus.php:41)
  at Symfony\Component\Messenger\TraceableMessageBus->dispatch(object(ReverseQuery))
     (vendor/symfony/messenger/HandleTrait.php:43)
  at Bus\MessengerQueryBus->handle(object(ReverseQuery))
     (src/redacted/Shared/Infrastructure/Bus/Query/MessengerQueryBus.php:37)
  at Bus\Query\MessengerQueryBus->ask(object(ReverseQuery))
     (src/Controller/ReverseGeocodingAction.php:45)
  at App\Controller\ReverseGeocodingAction->__invoke(object(Request), 43.5798704, 7.1205716, 'fr')
     (vendor/symfony/http-kernel/HttpKernel.php:163)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:75)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:202)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php:35)
  at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
     (vendor/autoload_runtime.php:35)
  at require_once('/var/www/redacted/vendor/autoload_runtime.php')
     (public/index.php:6)                             
jbelien commented 1 year ago

Thanks, could you also provide the piece of code that triggers that error message ?

The issue seems to come from PluginProvider when your query seems to fail and return a GeocoderRejectedPromise.

Being able to see your code will help me to replicate it and debug it.

garak commented 1 year ago

This is the relevant part of the class:

class PluginProvider
{
    private function createPluginChain(array $pluginList, callable $clientCallable)
    {
        $firstCallable = $lastCallable = $clientCallable;

        while ($plugin = array_pop($pluginList)) {
            $lastCallable = function (Query $query) use ($plugin, $lastCallable, &$firstCallable) {
                // XXX this is line 148
                return $plugin->handleQuery($query, $lastCallable, $firstCallable);
            };

            $firstCallable = $lastCallable;
        }

        $firstCalls = 0;

        return function (Query $query) use ($lastCallable, &$firstCalls) {
            if ($firstCalls > $this->options['max_restarts']) {
                throw LoopException::create('Too many restarts in plugin provider', $query);
            }

            ++$firstCalls;

            return $lastCallable($query);
        };
    }
}
jbelien commented 1 year ago

Thanks but that seems to be only custom code. Could you also provide the Geocoder related code. What plugins do you use ? Are you not confusing plugins and providers ?

garak commented 1 year ago

The code is a copy of the one in PluginProvider.php except that the variable $firstCallable is omitted since it's useless). The plugin is GoogleMaps

garak commented 1 year ago

I found finally that the problem occurs only when I don't set proper values for Google API key. Nevertheless, I think an exception should be provided instead of the current error