Skip to content
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

Regression in 10.0.19: Error: Cannot determine a GraphQL input type ("....") for the "...". Make sure your class is decorated with an appropriate decorator. at InputTypeFactory.create #2360

Closed
2 of 4 tasks
andreialecu opened this issue Aug 26, 2022 · 10 comments

Comments

@andreialecu
Copy link
Contributor

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

After upgrading to 10.0.22 I started getting a weird error about in a pretty big project:

Error: Cannot determine a GraphQL input type ("ClubModel") for the "club". Make sure your class is decorated with an appropriate decorator.
    at InputTypeFactory.create

There was no context as to where this error originated, so I had to add various console.logs inside @nestjs/graphql to find it.

I eventually tracked it down to this piece of code:

image

The error was about an InputType being expected on a @ResolveField() so this is very bizarre.

Here's the relevant code:

const isAbstract = getAppCaller() === AppCaller.PublicApi ? true : false;

function resolveType(value: { kind: typeof ALL_CLOCK_UNIT_KINDS[number] }) {
  return ALL_CLOCK_UNIT_MODELS.find((c) => c.kind === value.kind);
}

@InterfaceType("ClockDeviceUnit", {
  isAbstract,
  resolveType,
})
@InputType("ClockDeviceUnitBaseInput", { isAbstract })
export class ClockDeviceUnitBaseModel {
  @prop({ type: () => String, required: true })
  kind!: ClockDeviceUnitKinds;

  @prop({ required: true })
  @Field()
  clubId!: string;
}

@Resolver(() => ClockDeviceUnitBaseModel)
export class ClockDeviceUnitResolver {
  constructor(private readonly clubService: ClubsService) {}

  @ResolveField(() => ClubModel)
  async club(@Parent() unit: ClockDeviceUnitBaseModel): Promise<ClubModel> {
    return this.clubService.getClub(unit.clubId);
  }
}

Minimum reproduction code

nope

Steps to reproduce

No response

Expected behavior

A @ResolveField() should not participate in inputs, I suspect a refactoring broke this.

Package version

10.0.19

Graphql version

No response

NestJS version

No response

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

@andreialecu
Copy link
Contributor Author

If I revert to 10.0.18 the error disappears, it appears in 10.0.19.

@JonnyBGod
Copy link

I have the same issue just for reference:

  @ResolveField(() => Organization)
  async organization(@Parent() { organizationId }: Invitation): Promise<Partial<Organization> | Error> {
    return this.organizationService.load(organizationId)
  }
@ObjectType()
@Directive('@key(fields: "_id")')
export class Organization {
  @Field(() => ObjectId)
  _id: ObjectId

  @Field(() => Date)
  createdAt: Date

  @Field(() => Date)
  updatedAt: Date
}

Error:

CannotDetermineInputTypeError: Cannot determine a GraphQL input type ("Organization") for the "organization". Make sure your class is decorated with an appropriate decorator.
    at InputTypeFactory.create (/Users/joaoribeiro/Projects/seeds/seed-backend/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type.factory.js:19:23)
    at /Users/joaoribeiro/Projects/seeds/seed-backend/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type-definition.factory.js:48:52
    at Array.forEach (<anonymous>)
    at /Users/joaoribeiro/Projects/seeds/seed-backend/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type-definition.factory.js:46:33

This still works properly for cases where I implement ObjectType and InputType simultaneous:

@ObjectType()
@InputType('MinimalUserInput')
export class MinimalUser extends PickType(User, [
  '_id',
  'name',
  'familyName',
  'givenName',
  'middleName',
  'nickname',
  'picture',
] as const) {
  @Field({ nullable: true })
  picture?: string
}

But I cannot do this with most of the cases because even apart from business logic constrains it then hit what it seams another bug where you cannot implement InputType and directives like "Key" or "shareable" with "InputType".

@kamilmysliwiec
Copy link
Member

This looks like a regression caused by this PR cc @roypeled #2212

Could any of you @andreialecu @JonnyBGod provide a minimum reproduction repository to help us fix this issue asap?

@JonnyBGod
Copy link

I am a bit busy but will try to get it for you later today.

There is another issue that maybe you can chack at the same time. Or if you prefer let me know and I will create a separate issue.

The problem shows when using ObjectType and InutType simultaneously and also applying directives such as Key and Shareable. It throws errors syaing that you cannot use these directives with InputType.
ideally it should ignore or dtripp these directives for the InputType metadata.

@CarsonF
Copy link
Contributor

CarsonF commented Aug 30, 2022

FWIW I worked around this by declaring the field on the entity.

class Entity {
  @Field(...)
  foo?: never;
}

@Resolver(Entity)
class Resolver {
  @ResolveField()
  foo() { ... }
}

@JonnyBGod
Copy link

Sorry did not manage to replicate with a simple repo yet. It looks odd, trying to replicate two of my entities simplified and it is working well on a simple repo. Also tried with abstract class extentions and still works.

Also removed most of my package versioning conflicts on my project (thought it could be a graphql version conflivting). still did not solve this.
Tried #2360 (comment) with no luck as well.

Will keep investigating...

andreialecu added a commit to andreialecu/nest-repro-2360 that referenced this issue Aug 31, 2022
@andreialecu
Copy link
Contributor Author

andreialecu commented Aug 31, 2022

@kamilmysliwiec repro at: https://github.com/andreialecu/nest-repro-2360

yarn start

...
Error: Cannot determine a GraphQL input type ("OtherEntity") for the "test123". Make sure your class is decorated with an appropriate decorator.
    at InputTypeFactory.create (/Users/andreialecu/Work/contrib/nestjs/nest-repro-2360/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type.factory.js:19:23)
    at /Users/andreialecu/Work/contrib/nestjs/nest-repro-2360/node_modules/@nestjs/graphql/dist/schema-builder/factories/input-type-definition.factory.js:48:52
    at Array.forEach (<anonymous>)

@andreialecu
Copy link
Contributor Author

As a side note: It would be great if the error message above pointed to something more specific for other cases where it is more legitimate.

In our actual project, we have similarly named fields across multiple resolvers. It was impossible to pinpoint which one it was throwing on without directly troubleshooting the NestJS source code.

@jhpierce
Copy link

I've run into the same issue, but I don't see much activity here - @andreialecu have you by any chance discovered a workaround?

@roypeled
Copy link
Contributor

Hey everyone, sorry for the late reply, I realize it was my refactor of metadata storage that caused this issue.
I didn't notice this issue before, and I just got an email with a comment update.

Here is the fix:
#2724

@kamilmysliwiec I would appreciate a merge, and if you can find the time to create a test for this case it would be amazing, I tried but for some reason I couldn't get the test to work with field resolver.

I did test the repro: https://github.com/andreialecu/nest-repro-2360 and the fix worked for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants