overblog / GraphQLBundle

This bundle provides tools to build a complete GraphQL API server in your Symfony App.
MIT License
788 stars 222 forks source link

non-existent parameter "container.build_id" #588

Closed videni closed 4 years ago

videni commented 5 years ago

hi, somehow I got this error, any fix please? I'm using Symfony4 and the master branch of this bundle commited at 7f4be04.

Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException: You have requested a non-existent parameter "container.build_id". in /Users/john/www/acme-application/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php:100
Stack trace:
#0 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php(67): Symfony\Component\DependencyInjection\ParameterBag\ParameterBag->get('container.build...')
#1 /Users/john/www/acme-application/vendor/symfony/dependency-injection/Container.php(112): Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag->get('container.build...')
#2 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1268): Symfony\Component\DependencyInjection\Container->getParameter('container.build...')
#3 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Parameter), Array, false)
#4 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1114): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array, false)
#5 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'cache.validator')
#6 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('cache.validator', 1, Array, false)
#7 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, false)
#8 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1114): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array, false)
#9 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, '.1_PhpArrayAdap...')
#10 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('.1_PhpArrayAdap...', 1, Array, false)
#11 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, false)
#12 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1114): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array, false)
#13 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'validator.mappi...')
#14 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('validator.mappi...', 1, Array, false)
#15 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, false)
#16 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1628): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array)
#17 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1166): Symfony\Component\DependencyInjection\ContainerBuilder->callMethod(Object(Symfony\Component\Validator\ValidatorBuilder), Array, Array)
#18 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'validator.build...')
#19 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('validator.build...', 1, Array, false)
#20 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1118): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, false)
#21 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'debug.validator...')
#22 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('debug.validator...', 1, Array, false)
#23 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, false)
#24 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1114): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array, false)
#25 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'debug.validator')
#26 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('debug.validator', 3, Array, false)
#27 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, false)
#28 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1114): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array, false)
#29 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'Overblog\\GraphQ...')
#30 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('Overblog\\GraphQ...', 1, Array, false)
#31 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\TypedReference), Array, false)
#32 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1114): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array, false)
#33 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'Overblog\\GraphQ...')
#34 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('Overblog\\GraphQ...', 1, Array, false)
#35 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, false)
#36 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1628): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array)
#37 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1166): Symfony\Component\DependencyInjection\ContainerBuilder->callMethod(Object(Overblog\GraphQLBundle\ExpressionLanguage\ExpressionLanguage), Array, Array)
#38 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'Overblog\\GraphQ...')
#39 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1264): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('Overblog\\GraphQ...', 1, Array, false)
#40 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1212): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, false)
#41 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1628): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Array, Array)
#42 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(1166): Symfony\Component\DependencyInjection\ContainerBuilder->callMethod(Object(Overblog\GraphQLBundle\Generator\TypeGenerator), Array, Array)
#43 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(610): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, true, 'Overblog\\GraphQ...')
#44 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(588): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('Overblog\\GraphQ...', 1, Array, true)
#45 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(556): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('overblog_graphq...', 1)
#46 /Users/john/www/acme-application/vendor/overblog/graphql-bundle/src/DependencyInjection/Compiler/TypeGeneratorPass.php(17): Symfony\Component\DependencyInjection\ContainerBuilder->get('overblog_graphq...')
#47 /Users/john/www/acme-application/vendor/symfony/dependency-injection/Compiler/Compiler.php(94): Overblog\GraphQLBundle\DependencyInjection\Compiler\TypeGeneratorPass->process(Object(Oro\Component\DependencyInjection\ExtendedContainerBuilder))
#48 /Users/john/www/acme-application/vendor/symfony/dependency-injection/ContainerBuilder.php(754): Symfony\Component\DependencyInjection\Compiler\Compiler->compile(Object(Oro\Component\DependencyInjection\ExtendedContainerBuilder))
#49 /Users/john/www/acme-application/vendor/symfony/http-kernel/Kernel.php(556): Symfony\Component\DependencyInjection\ContainerBuilder->compile()
#50 /Users/john/www/acme-application/vendor/symfony/http-kernel/Kernel.php(133): Symfony\Component\HttpKernel\Kernel->initializeContainer()
#51 /Users/john/www/acme-application/vendor/lchrusciel/api-test-case/src/ApiTestCase.php(80): Symfony\Component\HttpKernel\Kernel->boot()
#52 phar:///usr/local/Cellar/phpunit/7.3.1/bin/phpunit/phpunit/Framework/TestSuite.php(703): ApiTestCase\ApiTestCase::createSharedKernel()
#53 phar:///usr/local/Cellar/phpunit/7.3.1/bin/phpunit/phpunit/Framework/TestSuite.php(750): PHPUnit\Framework\TestSuite->run(Object(PHPUnit\Framework\TestResult))
#54 phar:///usr/local/Cellar/phpunit/7.3.1/bin/phpunit/phpunit/TextUI/TestRunner.php(587): PHPUnit\Framework\TestSuite->run(Object(PHPUnit\Framework\TestResult))
#55 phar:///usr/local/Cellar/phpunit/7.3.1/bin/phpunit/phpunit/TextUI/Command.php(203): PHPUnit\TextUI\TestRunner->doRun(Object(PHPUnit\Framework\TestSuite), Array, true)
#56 phar:///usr/local/Cellar/phpunit/7.3.1/bin/phpunit/phpunit/TextUI/Command.php(159): PHPUnit\TextUI\Command->run(Array, true)
#57 /usr/local/Cellar/phpunit/7.3.1/bin/phpunit(595): PHPUnit\TextUI\Command::main()
#58 {main}
videni commented 5 years ago

the TypeGeneratorPass is registerred before removing,

        $container->addCompilerPass(new TypeGeneratorPass(), PassConfig::TYPE_BEFORE_REMOVING);

the cache.validator service is dependent on 'cache.adapter.filesystem , its third argument is injected as below. apparently , the FrameworkExtension runs before any other compile passes, why the container.build_id is not ready when TypeGeneratorPass runs? It can't be removed before the PassConfig::TYPE_BEFORE_REMOVING phrase, I don't find any place to remove this parameter.

symfony/framework-bundle/DependencyInjection/FrameworkExtension.php

registerCacheConfiguration method

 $version = new Parameter('container.build_id');
      //...
  $container->getDefinition('cache.adapter.system')->replaceArgument(2, $version);
mcg-web commented 5 years ago

Hi can you provide the Symfony version used and an example of the bundle configuration please ?

Vincz commented 5 years ago

I can confirm that I have the same behavior. In production environment only and I'm running Symfony 4.3.5

mcg-web commented 5 years ago

@Vincz thanks for the version, do you have a way to bypass this issue or a simple example to reproduce this error?

Vincz commented 5 years ago

The way to bypass it is by adding a parameter:

parameters:
    container.build_id: ~

Not sure if there is side effects or not.

It looks like it is related to

$container->addCompilerPass(new TypeGeneratorPass(), PassConfig::TYPE_BEFORE_REMOVING);

And in the TypeGeneratorPass, the problem come from this :

$container->get('overblog_graphql.cache_compiler')

It happens only in production.

Sorry mate, didn't had the time to look deeper :-/

videni commented 5 years ago

@Vincz , do you have "rollerworks/password-strength-bundle"? for me it happens in test enviroment, my code base is quite large, lots of private bundles, still not successfull to find out the one which causes the trouble.

I create a demo, specially installed with rollerworks/password-strength-bundle, the error shows in prod, but not in test and dev enviroment. by the way it doesn't happen when set overblog/GraphQLBundle version to ^0.12.3.

migo315 commented 5 years ago

Have same problem after updating from ^0.12.3 to dev-master because I wanted to use the validator feature. Only happens in production. The workaround from @Vincz seems to work. But I don't know any side effects too.

Vincz commented 5 years ago

@videni Hi :) No, I don't use this bundle. I'll try to dig deeper in the coming days.

osavchenko commented 4 years ago

Hi there! Got same error, but on version 0.13.1 (with symfony 4.3.10) and in test env. And when I comment this line this problem disappears. BTW, on version 0.12.6 and the same symfony version - no errors.

bjoernr-de commented 4 years ago

Same issue on Symfony 5.0.4 in prod env - no issues in dev env.

$ composer require overblog/graphql-bundle
Using version ^0.13.1 for overblog/graphql-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "5.0.*"

Prefetching 3 packages 🎶 💨
  - Downloading (100%)

Package operations: 3 installs, 0 updates, 0 removals
  - Installing webonyx/graphql-php (v0.13.8): Loading from cache
  - Installing symfony/expression-language (v5.0.4): Loading from cache
  - Installing overblog/graphql-bundle (v0.13.1): Loading from cache
Writing lock file
Generating autoload files
ocramius/package-versions: Generating version class...
ocramius/package-versions: ...done generating version class
Symfony operations: 1 recipe (3b6bfbc8c219d43f18836157c495294c)
  -  WARNING  overblog/graphql-bundle (>=0.12): From github.com/symfony/recipes-contrib:master
    The recipe for this package comes from the "contrib" repository, which is open to community contributions.
    Review the recipe at https://github.com/symfony/recipes-contrib/tree/master/overblog/graphql-bundle/0.12

    Do you want to execute this recipe?
    [y] Yes
    [n] No
    [a] Yes for all packages, only for the current installation session
    [p] Yes permanently, never ask again for this project
    (defaults to n): y
  - Configuring overblog/graphql-bundle (>=0.12): From github.com/symfony/recipes-contrib:master
Executing script cache:clear [KO]
 [KO]
Script cache:clear returned with error code 1
!!  
!!   // Clearing the cache for the prod environment with debug                      
!!   // false                                                                       
!!  
!!  
!!  In ParameterBag.php line 98:
!!                                                                       
!!    You have requested a non-existent parameter "container.build_id".             
$ bin/console cache:clear

 // Clearing the cache for the prod environment with debug                      
 // false                                                                       

In ParameterBag.php line 98:

  You have requested a non-existent parameter "container.build_id".                                                     

once the package is removed, everything works fine:

$ composer remove overblog/graphql-bundle
overblog/graphql-bundle is not required in your composer.json and has not been removed
Dependency "symfony/framework-bundle" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "5.0.*"
Package operations: 0 installs, 0 updates, 3 removals
  - Removing webonyx/graphql-php (v0.13.8)
  - Removing symfony/expression-language (v5.0.4)
  - Removing overblog/graphql-bundle (v0.13.1)
Writing lock file
Generating autoload files
ocramius/package-versions: Generating version class...
ocramius/package-versions: ...done generating version class
Symfony operations: 1 recipe (899a51917f0e050d4b4b4f65cc9b876c)
  - Unconfiguring overblog/graphql-bundle (>=0.12): From github.com/symfony/recipes-contrib:master
Executing script cache:clear [OK]
Executing script assets:install public [OK]
$ bin/console cache:clear

 // Clearing the cache for the prod environment with debug                      
 // false                                                                       

 [OK] Cache for the "prod" environment (debug=false) was successfully cleared.  
bjoernr-de commented 4 years ago

☝️ this issue happens only with the latest version (=0.13.1) of GraphQLBundle.

The way to bypass it is by adding a parameter:

parameters:
    container.build_id: ~

Not sure if there is side effects or not.

Adding the mentioned parameter does not fix the issue but gives me another error then...

!!  
!!  Fatal error: Uncaught TypeError: Argument 3 passed to Symfony\Component\Cache\Adapter\AbstractAdapter::createSystemCache() must be of the type string, null given, called in /app/symfony/vendor/symfony/dependency-injection/ContainerBuilder.php on line 1076 and defined in /app/symfony/vendor/symfony/cache/Adapter/AbstractAdapter.php:104
!!  Stack trace:
!!  #0 /app/symfony/vendor/symfony/dependency-injection/ContainerBuilder.php(1076): Symfony\Component\Cache\Adapter\AbstractAdapter::createSystemCache('oyFjZY6rCz', 0, NULL, '/app/symfony/va...', Object(Symfony\Bridge\Monolog\Logger))
!!  #1 /app/symfony/vendor/symfony/dependency-injection/ContainerBuilder.php(595): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, false, 'cache.validator')
!!  #2 /app/symfony/vendor/symfony/dependency-injection/ContainerBuilder.php(1211): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('cache.validator', 1, Array, false)
!!  #3 /app/symfony/vendor/symfony/depende in /app/symfony/vendor/symfony/cache/Adapter/AbstractAdapter.php on line 104

Anyway no errors with version 0.12.6 and the same setup.

jourdan-qe commented 4 years ago

I confirm it works OK with 0.12.6

Would be great to fix this with the next release Thanks

jorrit commented 4 years ago

AFAIK this happens because all kinds of caches are enabled when APP_DEBUG is 0. The caches require container.build_id to be present, which I assume is only available after the container is built.

A hacky solution that works for me is this:

In TypeGeneratorPass->process() I add these blocks of code:

        $parameterBag = $container->getParameterBag();
        if (!$container->getParameter('kernel.debug')) {
            $parameterBag->set('container.build_id', 'graphqlbundle-pass-'.time());
        }

and

        if (!$container->getParameter('kernel.debug')) {
            $parameterBag->remove('container.build_id');
        }

around

       $generatedClasses = $container->get('overblog_graphql.cache_compiler')
            ->compile(TypeGenerator::MODE_MAPPING_ONLY);

I hope anyone has a solution less hacky.

jorrit commented 4 years ago

I have looked into this some more and the change between 0.12.6 and 0.13.1 that causes this error is the addition of ArgumentsTransformer to the constructor of ExpressionLanguage\ExpressionFunction\GraphQL\Arguments in commit 8ac73c88af1efc9f0f8d6cfad5a991723cc20d78.

It seems that it is not recommended to use the container while it is being compiled:

As a rule, only work with services definition in a compiler pass and do not create service instances. In practice, this means using the methods has(), findDefinition(), getDefinition(), setDefinition(), etc. instead of get(), set(), etc.

See https://symfony.com/doc/current/components/dependency_injection/compilation.html#execute-code-during-compilation

This happens in TypeGeneratorPass. It would be best if the $container->get() call would be removed, but I don't know how to implement the required functionality without it. We could try to instantiate the TypeGenerator directly, but then we lose the ability to have the service overridden by the user.

adri commented 4 years ago

Same issue here using Symfony v4.4.7 while trying to update overblog/graphql-bundle from 0.12.6 to 0.13.2. Is anyone running version > 0.13.1 in production with success?

sgehrig commented 4 years ago

The issue is that in general the changes done to the expression language functions are incompatible with the expression language component. The expression language functions are not designed to take services as constructor arguments. Instead they must rely on dependencies passed into the function during execution. So, taking the Arguments example that seems to cause the issue in the first place (https://github.com/overblog/GraphQLBundle/blob/master/src/ExpressionLanguage/ExpressionFunction/GraphQL/Arguments.php), the source code should look more like:

final class Arguments extends ExpressionFunction
{
    public function __construct()
    {
        parent::__construct(
            'arguments',
            function ($mapping, $data) {
                return "\$globalVariable->get('container')
                                        ->get('overblog_graphql.arguments_transformer')
                                        ->getArguments($mapping, $data, \$info)";
            },
            function ($arguments, $mapping, $data) {
                return $arguments['globalVariable']->get('container')
                                                   ->get('overblog_graphql.arguments_transformer')
                                                   ->getArguments($mapping, $data, $arguments['info']);
            }
        );
    }
}

Please note the similarity between the function compiler and the evaluator. While the compiler gets its dependencies injected, the evaluator however must retrieve its dependencies from the fist function parameter $arguments.

adri commented 4 years ago

@murtukov are you maybe aware of a different way of implementing this? See this and this comment.

Link to the original PR of this change: https://github.com/overblog/GraphQLBundle/pull/536

camirot commented 4 years ago

I have looked into this some more and the change between 0.12.6 and 0.13.1 that causes this error is the addition of ArgumentsTransformer to the constructor of ExpressionLanguage\ExpressionFunction\GraphQL\Arguments in commit 8ac73c8.

It seems that it is not recommended to use the container while it is being compiled:

As a rule, only work with services definition in a compiler pass and do not create service instances. In practice, this means using the methods has(), findDefinition(), getDefinition(), setDefinition(), etc. instead of get(), set(), etc.

See https://symfony.com/doc/current/components/dependency_injection/compilation.html#execute-code-during-compilation

This happens in TypeGeneratorPass. It would be best if the $container->get() call would be removed, but I don't know how to implement the required functionality without it. We could try to instantiate the TypeGenerator directly, but then we lose the ability to have the service overridden by the user.

I agree with @jorrit on this. It causes a lot of problems when using bundles that heavily depends on Dependency Injection to make deep changes in the application (i.e. https://github.com/dmaicher/doctrine-test-bundle), because it forces the compiler to generate container services earlier than expected (see https://github.com/dmaicher/doctrine-test-bundle/issues/117). I can't think of a solution right now but I'll look into it. In the meantime, if someone has experience in DI, feel free to help =)

Quick (and probably dirty) workaround:

-        $generatedClasses = $container->get('overblog_graphql.cache_compiler')
-            ->compile(TypeGenerator::MODE_MAPPING_ONLY);
+        $compilerService = $container->getAlias('overblog_graphql.cache_compiler')->__toString();
+        $definition = $container->getDefinition($compilerService);
+        $args = $definition->getArguments();
+
+        // At this point, $configs might still not be resolved
+        if (is_string($args[3]) && !empty($args[3])) {
+            if (stripos($args[3], "%%env(") === 0) // Resolve env placeholder
+                $args[3] = $container->resolveEnvPlaceholders($args[3]);
+            else if ($args[3][0] == '%') // Resolve parameter
+                $args[3] = $container->getParameter(substr($args[3], 1, strlen($args[3]) - 2));
+        }
+
+        // Use a temporary cache compiler instance to get the generated classes
+        $generator = $definition->getClass();
+        $typeGenerator = new $generator(...$args);
+        $generatedClasses = $typeGenerator->compile(TypeGenerator::MODE_MAPPING_ONLY);
mathroc commented 4 years ago

beware, this workaround:

parameters:
    container.build_id: ~

caused me some issue when upgrading to Symfony 5, in prod env (or any env without debug enabled)

it cause this error:

Fatal error: Uncaught TypeError: Argument 3 passed to Symfony\Component\Cache\Adapter\AbstractAdapter::createSystemCache() must be of the type string, null given, called in /scripts/api/var/cache/qa/ContainerB1XIgLp/getCache_AnnotationsService.php on line 14 and defined in /scripts/api/vendor/symfony/cache/Adapter/AbstractAdapter.php:104 Stack trace:

0 /scripts/api/var/cache/qa/ContainerB1XIgLp/getCache_AnnotationsService.php(14): Symfony\Component\Cache\Adapter\AbstractAdapter::createSystemCache('v3dW6ZGpEj', 0, NULL, '/scripts/api/va...', Object(Symfony\Bridge\Monolog\Logger))

1 /scripts/api/var/cache/qa/ContainerB1XIgLp/App_KernelQaDebugContainer.php(764): require('/scripts/api/va...')

2 /scripts/api/var/cache/qa/ContainerB1XIgLp/getAnnotations_CacheService.php(14): ContainerB1XIgLp\App_KernelQaDebugContainer->load('getCache_Annota...')

3 /scripts/api/var/cache/qa/ContainerB1XIgLp/App_KernelQaDebugContainer.php(764): require('/scripts/api/va...')

4 /scripts/api/var/cache/qa/ContainerB1XIgLp/App_KernelQaDebugContai in /scripts/api/vendor/symfony/cache/Adapter/AbstractAdapter.php on line 104

that’s because the build_id is used at a place expecting a string, for now I updated the workaround like this:

parameters:
    container.build_id: "a fake build id"
murtukov commented 4 years ago

@jorrit @migo315 @mathroc @bjoernr-de @osavchenko @adri

Do you still have this issue? I can't reproduce it. I've tried fresh installs of Symfony 4.3.10 and 4.4.7 with versions 0.13.1 and 0.13.2.

deeky666 commented 4 years ago

@murtukov still happens here with Symfony 5.1.2 and 0.13.2

murtukov commented 4 years ago

@deeky666 could you show your composer.json file?

deeky666 commented 4 years ago

@murtukov you can reproduce it with the following command (I used the Symfony installer in this example):

symfony new demo && cd demo && composer req overblog/graphql-bundle symfony/validator && bin/console --no-debug

The problem arises when using the Symfony Validator component, but I guess it could happen with any other package, too. Hope that helps.

sgehrig commented 4 years ago

I've just added a PR #697 to fix the issues mentioned in my comment above (https://github.com/overblog/GraphQLBundle/issues/588#issuecomment-610393275). This should fix the underlying issue of setting up the expression language functions in a compiled container.

mcg-web commented 4 years ago

The fix has been released in v0.13.3, I'm closing this one. Thank you @sgehrig :+1: