-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exception "You must freeze() a MutableObjectType before fetching its fields" gets thrown #308
Comments
Hey @PhilippSchreiber , Could you explain a bit more in details how I could reproduce this? From what I understand, you are using GraphQLite with the Symfony GraphQL bundle. |
Hi @moufmouf , I try ;) I'm using the thecodingmachine/graphqlite-bundle ^4.0 The error appears in graphiql just when it tries to generate the schema – so it should be an empty graphql request, correct. All other requests work. I am available for testing / debugging if you need help. |
Hey @moufmouf. I'm getting this error as well - came here to discuss, actually. Please see the following stack-trace:
Now, I've started digging, in order to eliminate the exact cause of the issue. I know what's causing it, but not precisely. At least in our case, the issue arose when we had an The same error also occurs if you have methods annotated with I don't personally have a preference on how this is resolved. The spec might actually have that answer. But, at any rate, an updated error message is needed to address this situation. |
@moufmouf I get this same error on 4.0.3 when I have an external User type, and an introspection is ran: /**
* @GraphQL\Type(class=User::class)
* @GraphQL\SourceField(name="id")
* @GraphQL\SourceField(name="email")
*/
class UserType
{
The exception is called on line 82 in public function getFields(): array
{
if ($this->finalFields === null) {
if ($this->status === MutableInterface::STATUS_PENDING) {
throw new RuntimeException('You must freeze() a MutableObjectType before fetching its fields.');
} It's checking the Any ideas how to get past this? |
If I comment out the exception, I get this as the next one:
If I then comment out this in the // $staticTypes[] = SymfonyUserInterfaceType::class; This is a super ugly workaround but it fixes the issue - adding this to my own Kernel's compiler pass: // Hack to get around bug of "You must freeze() a MutableObjectType before fetching its fields."
// @see https://github.com/thecodingmachine/graphqlite/issues/308
$staticClassListTypeMapperFactoryDefinition = $container->getDefinition(StaticClassListTypeMapperFactory::class);
foreach ($staticClassListTypeMapperFactoryDefinition->getArguments() as $argumentKey => $argumentVal)
{
if (is_array($argumentVal))
{
foreach ($argumentVal as $key => $val)
{
if ($val === SymfonyUserInterfaceType::class)
{
unset($argumentVal[$key]);
$staticClassListTypeMapperFactoryDefinition->setArgument($argumentKey, $argumentVal);
}
}
}
} |
@MattBred did you figure out what was wrong in your case? In my case it was due to a duplicate type being registered. |
@oojacoboo I didn't dive deep enough to resolve the problem in the library - just my fix above. From what I can remember, declaring an external User type that is based on a User class that implements UserInterface will throw this error on introspection. Something about it conflicting with the internal GraphQLite user type. |
So, I've run into this issue again. There is, without a doubt, issues with the interface implementation. I went ahead and used a union return type annotation to get around the issue - not happy about it though. I suspect that the issue is related to interfaces having a subset of fields from the type implementing them causing GraphQLite to treat them as separate types (failing comparison), generating a new type "on the fly" and then using the actual interface as well. This causes there to be duplicate types attempting to be mapped. I'm assuming that the GraphQL spec doesn't require that the fields of an interface be the same as the fields of the type implementing it? @moufmouf any ideas on this? Also, where is this code being handled? The stack traces are virtually impossible to use as it's all webonyx internals. Where are these types being registered to take a look at this logic? |
Ran into this issue as well, it occurred when I turned off |
I can confirm this. I set |
|
Same issue.
will avoid calling method \TheCodingMachine\GraphQLite\Mappers\RecursiveTypeMapper::mapClassToType, where interface "freezing" happens. BUT! Here's pretty strange way to fix it ;D. After adding child type in query - it doesn't throw any error:
I think, problem is that graphQl can work with interface-types only, if they are resolved as dependencies of parent types. Another strange way to fix it: declare somewhere query with output type "PricePerUnitInterface"... Still don't understand how it works... Here are:
Hope, it will help an invastigation. Sorry for my english. |
Man, you saved my day! It indeed works but there isn't enough when they are declared SOMEWHERE, rather they had to be in the same class where the problematic query is. I've given them opaque random names and they throw "not implemented" exception.
This works as well, but I didn't like that too much as it means the hack has to be implemented client-side. Which is not ideal, obviously :-) |
One more point. If you have a mutation that throws this "freeze" exception, you have to declare a MUTATION with output type "PricePerUnitInterface" in the same class. |
It gets thrown in MutableTrait in line 82. When I add a print_r there for $this->className I can see that the problem is in "Symfony\Component\Security\Core\User\UserInterface".
Does anyone have a clue what I can do? It only happens when posting to the /graphql endpoint without query / mutation. But this leads to no autocomplete since the schema doesn't get generated. Queries and mutations work as expected.
The text was updated successfully, but these errors were encountered: