Closed videni closed 4 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);
Hi can you provide the Symfony version used and an example of the bundle configuration please ?
I can confirm that I have the same behavior. In production environment only and I'm running Symfony 4.3.5
@Vincz thanks for the version, do you have a way to bypass this issue or a simple example to reproduce this error?
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 :-/
@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
.
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.
@videni Hi :) No, I don't use this bundle. I'll try to dig deeper in the coming days.
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.
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.
☝️ 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.
I confirm it works OK with 0.12.6
Would be great to fix this with the next release Thanks
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.
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.
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.
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?
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
.
@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
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 ofExpressionLanguage\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.
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 theTypeGenerator
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);
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"
@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.
@murtukov still happens here with Symfony 5.1.2 and 0.13.2
@deeky666 could you show your composer.json file?
@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.
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.
The fix has been released in v0.13.3, I'm closing this one. Thank you @sgehrig :+1:
hi, somehow I got this error, any fix please? I'm using Symfony4 and the master branch of this bundle commited at
7f4be04
.