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

Cannot read properties of null (reading '__helper') #4688

Closed
sawa-ko opened this issue Sep 10, 2023 · 6 comments
Closed

Cannot read properties of null (reading '__helper') #4688

sawa-ko opened this issue Sep 10, 2023 · 6 comments

Comments

@sawa-ko
Copy link
Contributor

sawa-ko commented Sep 10, 2023

Describe the bug
I have a users entity that references several entities, so what I try to do is to use the fields property of the query to limit which fields to show from the nested properties, but then when I try to limit the properties of the owner field of the projectmembers entity from the project entity then I get the error Cannot read properties of null (reading '__helper').

My project is open source, and you can see who is causing the error here:
https://github.com/kent-0/api/blob/main/src/modules/auth/services/account.service.ts#L126-L174

If you need to run the project, there is an (https://github.com/kent-0/api/blob/main/.env.example) file that you just need to rename to .env and set its values.

Stack trace

[Nest] 18624  - 09/10/2023, 5:27:20 PM   ERROR [ExceptionsHandler] Cannot read properties of null (reading '__helper')
TypeError: Cannot read properties of null (reading '__helper')
    at helper (/home/sawa/personal/backend/api/node_modules/.pnpm/@mikro-orm+core@5.8.0_@mikro-orm+migrations@5.8.0_@mikro-orm+postgresql@5.8.0_@mikro-orm+seeder@5.8.0/node_modules/@mikro-orm/core/entity/wrap.js:21:19)
    at /home/sawa/personal/backend/api/node_modules/.pnpm/@mikro-orm+core@5.8.0_@mikro-orm+migrations@5.8.0_@mikro-orm+postgresql@5.8.0_@mikro-orm+seeder@5.8.0/node_modules/@mikro-orm/core/entity/EntityFactory.js:103:48
    at Array.forEach (<anonymous>)
    at EntityFactory.mergeData (/home/sawa/personal/backend/api/node_modules/.pnpm/@mikro-orm+core@5.8.0_@mikro-orm+migrations@5.8.0_@mikro-orm+postgresql@5.8.0_@mikro-orm+seeder@5.8.0/node_modules/@mikro-orm/core/entity/EntityFactory.js:100:28)
    at EntityFactory.create (/home/sawa/personal/backend/api/node_modules/.pnpm/@mikro-orm+core@5.8.0_@mikro-orm+migrations@5.8.0_@mikro-orm+postgresql@5.8.0_@mikro-orm+seeder@5.8.0/node_modules/@mikro-orm/core/entity/EntityFactory.js:42:18)
    at SqlEntityManager.findOne (/home/sawa/personal/backend/api/node_modules/.pnpm/@mikro-orm+core@5.8.0_@mikro-orm+migrations@5.8.0_@mikro-orm+postgresql@5.8.0_@mikro-orm+seeder@5.8.0/node_modules/@mikro-orm/core/EntityManager.js:372:35)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at AuthAccountService.me (/home/sawa/personal/backend/api/src/modules/auth/services/account.service.ts:128:18)
    at target (/home/sawa/personal/backend/api/node_modules/.pnpm/@nestjs+core@10.2.4_@nestjs+common@10.2.4_@nestjs+platform-express@10.2.4_reflect-metadata@0.1.13_rxjs@7.8.1/node_modules/@nestjs/core/helpers/external-context-creator.js:74:28)
    at Object.accountMe (/home/sawa/personal/backend/api/node_modules/.pnpm/@nestjs+core@10.2.4_@nestjs+common@10.2.4_@nestjs+platform-express@10.2.4_reflect-metadata@0.1.13_rxjs@7.8.1/node_modules/@nestjs/core/helpers/external-proxy.js:9:24)

To Reproduce
Steps to reproduce the behavior:

const user = await this.usersRespository.findOne(
      {
        id: userId,
      },
      {
        fields: [
          'biography',
          'createdAt',
          'first_name',
          'last_name',
          'username',
          'id',
          'projects.project.description',
          'projects.project.end_date',
          'projects.project.id',
          'projects.project.name',
          'projects.project.owner.id',
          'projects.project.owner.username',
          'projects.project.owner.first_name',
          'projects.project.owner.last_name',
          'projects.project.start_date',
          'projects.roles.id',
          'projects.roles.name',
          'projects.roles.permissions',
          'email.value',
          'email.is_confirmed',
        ],
        populate: [
          'email',
          'projects',
          'projects.project',
          'projects.project.roles',
          'projects.project.owner',
        ],
      },
    );

Expected behavior
Result of the relationship of the property owner of the entity project members of the entity project resolved correctly with the fields that were set to view.

Additional context
I am using mikro-orm with nestjs and I am using postgres as database.

Versions

Dependency Version
node v20.6.0
typescript 5.2.2
mikro-orm 5.8.0
your-driver postgres
@B4nan
Copy link
Member

B4nan commented Sep 11, 2023

Can you please provide minimal reproduction? So a script, no additional dependencies, no web servers, no GQL...

@sawa-ko
Copy link
Contributor Author

sawa-ko commented Sep 11, 2023

Hello @B4nan!
I tried to replicate the problem without using graphql but I could not replicate the problem using the nestjs controllers, only using graphql.

Update, I have found out who causes it: Apparently when I do this query in the guard using the token entity, that's when the error appears, if I don't do that query, everything works fine.

https://github.com/kent-0/api/blob/main/src/modules/auth/strategy/jwt.strategy.ts#L96-L122

Knowing that, I will try to replicate the error.

Update 2: I have not been able to replicate it again in another project. :(

@sawa-ko
Copy link
Contributor Author

sawa-ko commented Sep 11, 2023

Problem solved. The problem came from this query:

	const tokenSession = await this.tokensRepository.findOne({
      revoked: false,
      token_type: TokenType.AUTH,
      token_value: token,
      user: payload.sub,
	});

That it was being used in an authentication guard: https://github.com/kent-0/api/blob/4865ad815431d8d5770bbd2ad39fe0c9db72675e/src/modules/auth/strategy/jwt.strategy.ts#L96-L101

Then changing it to:

    const tokenSession = await this.em.fork().findOne(AuthTokensEntity, {
      revoked: false,
      token_type: TokenType.AUTH,
      token_value: token,
      user: payload.sub,
    });

It has worked correctly now.

@B4nan
Copy link
Member

B4nan commented Sep 11, 2023

So it's about contexts, you apparently have something loaded to the context that affects the following query and hydration.

Btw I see you have forceEntityConstructor enabled, may I ask why? I've started to see this flag way too often, and up until now, everyone just misunderstood what it does. I don't see any place in your app that would require it, do you understand that the entities are created with the same class prototype regardless of it? It only controls whether your managed entity (so loaded from he database) fires the constructor or not, there are no other differences (e.g. both ways will support instanceof checks, will have the class methods, etc).

@rubiin
Copy link
Contributor

rubiin commented Sep 12, 2023

Looks more to me like a code issue rather than an orm issue. Since its solved , i think it can be closed

@B4nan
Copy link
Member

B4nan commented Sep 12, 2023

Well, it's not solved, he just worked it around by using a clear context. Even if it would be a context issue, this is an error that shouldn't happen, it's not some validation but a TypeError.

I guess I will just add a check to that specific line where it throws...

@B4nan B4nan closed this as completed in f6e8204 Sep 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants