Mahesh Kurakula
Mahesh Kurakula

Reputation: 73

Nest js throttler with GraphQL is not working as expected

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
  getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gqlCtx.getContext();
    return { req: ctx.req, res: ctx.res };
  }
}

Here I am getting only req from ctx, res is undefined. I am using GraphQL with express in nestjs.

This is how my context object looks like before creating a GqlExecutionContext:

    ExecutionContextHost {
  args: [
    undefined,
    { id: 2 },
    { req: [IncomingMessage] },
    {
      fieldName: 'user',
      fieldNodes: [Array],
      returnType: User!,
      parentType: Query,
      path: [Object],
      schema: [GraphQLSchema],
      fragments: [Object: null prototype] {},
      rootValue: undefined,
      operation: [Object],
      variableValues: {},
      cacheControl: [Object]
    }
  ],
  constructorRef: [class UsersResolver],
  handler: [Function: findOne],
  contextType: 'graphql'
}

Error:

[Nest] 30284  - 08/01/2022, 12:54:25 am   ERROR [ExceptionsHandler] Cannot read property 'ip' of undefined
TypeError: Cannot read property 'ip' of undefined
    at ThrottlerGuard.getTracker (C:\Users\Mahesh\OneDrive\Desktop\graphql-server\node_modules\@nestjs\throttler\dist\throttler.guard.js:95:16)

Upvotes: 2

Views: 2066

Answers (2)

Phan Văn Tiến
Phan Văn Tiến

Reputation: 109

In my case, I got the following error message

cannot read property 'header' of undefined

I think the main problem comes from the ctx.res which is undefined. To resolved the problem I used the following code:

ctx.req.res

In your case it should be:

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gqlCtx.getContext();
    return { req: ctx.req, res: ctx.req.res };
  }
}

Upvotes: 7

Mahesh Kurakula
Mahesh Kurakula

Reputation: 73

I have added the req, res to the context in GraphQLModule.forRoot() So after creating Graphql execution context I am able to get the required data in the return statement { req: ctx.req, res: ctx.res }.

GraphQLModule.forRoot({
  autoSchemaFile: 'src/graphql-schema.gql',
  context: ({ req, res }) => ({ req, res }),
}),

Upvotes: 4

Related Questions