-
Notifications
You must be signed in to change notification settings - Fork 419
Description
Did you read the migration guide?
- I have read the whole migration guide
Is there an existing issue that is already proposing this?
- I have searched the existing issues
Potential Commit/PR that introduced the regression
No response
Versions
^13.1.0
Describe the regression
I have upgrade the @nestjs/* specific version in my package.json file to latest using ncu -u -f /^@nestjs/
. I'm on version 10.x.x earlier. Also updated Nx from v13 to v20 and @apollo/server to 4.21.1
After migration, the application build was successful and nx run my-app:serve
had no errors and listening to port localhost:3333.
But when I try to access Graphql playground in chrome browser, I'm seeing a 500 status code error. will INTERNAL server error.
The context from Graphql module was not returning the expected res
and req
data.
Here is the error on logs:
[Nest] 41096 - 2025-05-22T16:35:30.019Z LOG [RestLogger - cid=47611fb2-6c66-4016-8fba-31c66e785241-pass-edge sid=DZofy-xXI_pjfTGbcpfG7ZMdCH59z2pP] << GET /.well-known/appspecific/com.chrome.devtools.json - duration=3 status=404
[Nest] 41096 - 2025-05-22T16:35:31.028Z LOG [RestLogger - cid=6ce1fac7-9085-4fb6-a7b6-697cd8b0c899-pass-edge sid=LGe3z5_gYhVc_TButobKmG5Ln11mk4YC] >> POST /graphql - host=localhost:3333
Unexpected error processing request: TypeError: Cannot read properties of undefined (reading 'req')
Why was context not returning the req object ? Any suggestion on fixing this.
Minimum reproduction code
import { join } from 'path';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { MiddlewareConsumer, Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ThrottlerModule } from '@nestjs/throttler';
import { joinPathFragments, workspaceRoot } from '@nx/devkit';
import { GraphQLError } from 'graphql';
import { allDataProviders } from './all.data-providers';
import { allResolvers } from './all.resolvers';
import { allServices } from './all.services';
import { AppController } from './app.controller';
import { CodesModule } from './codes/codes.module';
import { RewardsResolver } from './resolvers/rewards.resolver';
import { AuthMiddleware } from './utility/auth-middleware';
import { GqlThrottlerGuard } from './utility/gql-throttle.guard';
import { GraphqlAuthGuard } from './utility/graphql-auth.guard';
import { GraphqlLogger } from './utility/graphql.logger';
import { STRICT_TRANSPORT_SECURITY_HEADER } from './utility/pass-state';
import { RestLogger } from './utility/rest.logger';
const typesDir = joinPathFragments(workspaceRoot, 'libs/data-access/common/edge/src');
// TODO: The modules are not dealt with in a consistent way. That should change. See PASS-1744 for details.
@Module({
imports: [
// Set to empty so that we aren't rate limiting all endpoints just yet
ThrottlerModule.forRoot(),
CodesModule,
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
typePaths: ['./**/*.graphql'],
path: process.env.XXXX || '/graphql',
playground: process.env.GRAPHQL_PLAYGROUND === 'true',
definitions: { path: join(typesDir, 'lib/graphql.ts') },
context: ({ req, res }) => {
res.header(STRICT_TRANSPORT_SECURITY_HEADER, 'max-age=31536000; includeSubDomains');
return { req, res };
},
formatError: (error: GraphQLError) => {
const graphqlError = !process.env.XXXXXX
? error
: (error as any)?.extensions?.exception?.response?.message || error?.message;
return error;
},
introspection: true,
}),
],
controllers: [AppController],
providers: [
...allServices,
...allDataProviders,
...allResolvers,
GraphqlLogger,
GraphqlAuthGuard,
GqlThrottlerGuard,
RewardsResolver,
],
})
export class AppModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(RestLogger).forRoutes('*');
consumer.apply(AuthMiddleware).forRoutes('graphql');
}
}
grapql.logger.ts
import { Plugin } from '@nestjs/apollo';
import { ApolloServerPlugin, GraphQLRequestListener } from 'apollo-server-plugin-base';
import { GraphQLRequestContext } from 'apollo-server-types';
import { PassState } from './pass-state';
import { LoggerSource } from './standard.logger';
@Plugin()
export class GraphqlLogger extends LoggerSource implements ApolloServerPlugin {
constructor() {
super('GraphQL');
}
async requestDidStart?(requestContext: GraphQLRequestContext): Promise<GraphQLRequestListener> {
const req = requestContext.context.req;
const state = this.recoverRequestState<PassState>(PassState, req) || new PassState(requestContext.context);
requestContext.context.state = this.rememberRequestState(PassState, req, state);
const logger = this.logger(state);
const { operationName, query } = requestContext.request;
const performLogging = operationName !== 'IntrospectionQuery'; // NOTE - this is a noisy playground operation
const startTime = Date.now();
const message = operationName
? `operation: ${operationName}`
: `statement: ${query.toString().replace(/\n/g, ' ').replace(/\s\s+/g, ' ').trim()}`;
if (performLogging) logger.log(`>> ${message}`);
return <GraphQLRequestListener>{
willSendResponse: async (_context): Promise<void> => {
const duration = Date.now() - startTime;
const { errors } = requestContext;
if (errors) logger.error(`!! ${message} - errors=${errors}`);
if (performLogging) logger.log(`<< ${message} - duration=${duration}`);
},
};
}
}
Expected behavior
Expecting requestContext to have context object and a successful 200 on http://localhost:3333/graphql
.
Other
Graphql playground network logs
{
"errors": [
{
"message": "Internal server error",
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"stacktrace": [
"Error: Internal server error",
" at internalExecuteOperation (/Users/user/workspace/frontend/onf-pass-frontend/node_modules/@apollo/server/src/ApolloServer.ts:1356:11)",
" at processTicksAndRejections (node:internal/process/task_queues:95:5)",
" at runHttpQuery (/Users/user/workspace/frontend/onf-pass-frontend/node_modules/@apollo/server/src/runHttpQuery.ts:232:27)",
" at runPotentiallyBatchedHttpQuery (/Users/abuggave/workspace/frontend/onf-pass-frontend/node_modules/@apollo/server/src/httpBatching.ts:85:12)",
" at ApolloServer.executeHTTPGraphQLRequest (/Users/abuggave/workspace/frontend/onf-pass-frontend/node_modules/@apollo/server/src/ApolloServer.ts:1109:14)"
]
}
}
]
}
My package.json
{
"dependencies": {
"@abyss/web": "1.66.0",
"@apollo/client": "3.13.8",
"@apollo/server": "^4.12.1",
"@aws-sdk/client-s3": "3.709.0",
"@aws-sdk/s3-request-presigner": "3.709.0",
"@datadog/browser-rum": "^4.9.0",
"@datadog/datadog-ci": "^2.18.1",
"@loadable/component": "^5.15.2",
"@loadable/server": "^5.15.2",
"@nestjs/apollo": "^13.1.0",
"@nestjs/common": "11.1.1",
"@nestjs/core": "11.1.1",
"@nestjs/graphql": "^13.1.0",
"@nestjs/platform-express": "11.1.1",
"@nestjs/swagger": "^11.2.0",
"@nestjs/throttler": "^6.4.0",
"@next/bundle-analyzer": "^12.1.6",
"@openapitools/openapi-generator-cli": "^2.5.1",
"@rally/advantage-components": "10.1.9",
"@rally/analytics": "2.6.0",
"@rally/creation-matrix": "^1.2.1",
"@rally/impersonation-tools": "^0.1.5",
"@rally/stylelint-config": "^2.0.3",
"@reduxjs/toolkit": "1.9.3",
"@types/react-paginate": "^7.1.4",
"@types/yargs": "^15.0.19",
"allure-commandline": "2.13.0",
"ansi-regex": "^6.0.1",
"apollo-server-core": "^3.13.0",
"apollo-server-express": "^3.13.0",
"apollo-server-types": "^3.8.0",
"apollo3-cache-persist": "^0.14.0",
"async-mutex": "^0.3.2",
"axios": "1.9.0",
"bcryptjs": "^2.4.3",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"classnames": "^2.3.1",
"connect-redis": "^6.0.0",
"cookie-parser": "^1.4.6",
"core-js": "3.36.1",
"cross-fetch": "^3.1.5",
"cypress-jest-adapter": "^0.1.1",
"date-fns": "^2.27.0",
"date-fns-tz": "^1.1.6",
"dd-trace": "^5.52.0",
"deepmerge": "^4.2.2",
"document-register-element": "1.13.1",
"dompurify": "^3.0.8",
"dot-env": "0.0.1",
"duplicate-package-checker-webpack-plugin": "^3.0.0",
"ecstatic": "^4.1.4",
"eslint-plugin-jest": "^26.9.0",
"express": "4.21.2",
"express-opentracing": "^0.1.1",
"express-session": "^1.17.2",
"fast_array_intersect": "^1.1.0",
"fast-array-diff": "^1.0.1",
"fast-json-stable-stringify": "^2.1.0",
"geodist": "^0.2.1",
"geolib": "^3.3.3",
"google-auth-library": ">=5.9.2",
"graphql": "^16.11.0",
"graphql-tools": "^8.1.0",
"hamburger-react": "^2.5.0",
"hasha": "^5.2.2",
"http-status-codes": "^2.1.4",
"ioredis": "^5.6.1",
"ismobilejs": "^1.1.1",
"isomorphic-unfetch": "^3.1.0",
"jest-svg-transformer": "^1.0.0",
"jest-transform-stub": "^2.0.0",
"jest-transform-yaml": "^1.0.0",
"js-yaml": "^4.1.0",
"jsonwebtoken": ">=8.5.1",
"lodash": "^4.17.21",
"lodash.mergewith": "^4.6.2",
"mock-apollo-client": "^1.2.0",
"moize": "^6.1.1",
"next": "14.2.3",
"next-connect": "0.12.2",
"next-images": "1.8.4",
"next-transpile-modules": "^9.0.0",
"normalizr": "^3.6.1",
"passkit-generator": "^3.1.6",
"postcss": "8.4.38",
"react": "18.3.1",
"react-card-flip": "^1.1.1",
"react-dom": "18.3.1",
"react-id-swiper": "^4.0.0",
"react-intersection-observer": "^9.3.3",
"react-intl": "^6.4.1",
"react-is": "18.3.1",
"react-loadable": "^5.5.0",
"react-lottie-hook": "^0.3.0",
"react-map-gl": "^6.1.17",
"react-modal": "^3.14.3",
"react-paginate": "^8.3.0",
"react-redux": "8.0.5",
"react-responsive": "^9.0.0-beta.4",
"react-router-dom": "6.11.2",
"react-select": "^5.10.1",
"react-singleton-hook": "^3.2.3",
"react-table": "^7.8.0",
"react-to-print": "^2.13.0",
"recurly": "^4.2.0",
"redis": "^3.1.2",
"redux": "^4.1.2",
"redux-dynamic-modules": "^5.2.3",
"reflect-metadata": "^0.1.13",
"regenerator-runtime": "0.13.7",
"request": "^2.88.2",
"rooks": "^5.7.3",
"rxjs": "^7.5.2",
"styled-components": "5.3.6",
"supertest": "^7.0.0",
"swagger-ui-express": "^4.1.6",
"swiper": "^6.5.9",
"ts-morph": "^25.0.0",
"tslib": "^2.4.0",
"typescript-fsa": "^3.0.0",
"universal-cookie": "^4.0.4",
"uuid": "^8.3.2",
"webpack": "^5.97.1",
"workerpool": "^6.1.5",
"yargs": "^16.2.0",
"@storybook/addon-interactions": "^8.2.8",
"storybook": "^8.2.8"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-decorators": "^7.14.5",
"@babel/plugin-transform-runtime": "^7.15.0",
"@babel/preset-env": "7.14.2",
"@babel/preset-react": "7.13.13",
"@babel/preset-typescript": "7.13.0",
"@graphql-eslint/eslint-plugin": "^3.20.1",
"@loadable/babel-plugin": "^5.13.2",
"@loadable/webpack-plugin": "^5.15.2",
"@nestjs/schematics": "11.0.5",
"@nestjs/testing": "11.1.1",
"@nx-tools/nx-docker": "^1.0.0-beta.4",
"@nx/devkit": "20.4.2",
"@nx/eslint-plugin": "20.4.2",
"@nx/express": "20.4.2",
"@nx/jest": "20.4.2",
"@nx/js": "20.4.2",
"@nx/nest": "20.4.2",
"@nx/next": "20.4.2",
"@nx/node": "20.4.2",
"@nx/react": "20.4.2",
"@nx/storybook": "20.4.2",
"@nx/web": "20.4.2",
"@nx/webpack": "20.4.2",
"@nx/workspace": "20.4.2",
"@storybook/addon-essentials": "8.6.14",
"@storybook/builder-webpack5": "7.4.5",
"@storybook/manager-webpack5": "6.5.16",
"@storybook/react": "8.6.14",
"@svgr/webpack": "^6.2.1",
"@swc/core": "1.5.29",
"@swc/jest": "0.2.38",
"@testcontainers/redis": "^10.25.0",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "16.1.0",
"@testing-library/user-event": "13.1.9",
"@types/cookie-parser": "^1.4.7",
"@types/express": "4.17.22",
"@types/express-session": "^1.17.4",
"@types/faker": "5.5.5",
"@types/jest": "29.5.14",
"@types/js-yaml": "^4.0.3",
"@types/jsonwebtoken": "^9.0.1",
"@types/loadable__component": "^5.13.3",
"@types/node": "18.19.103",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.0",
"@types/react-is": "18.3.0",
"@types/react-modal": "^3.12.1",
"@types/react-table": "^7.7.12",
"@types/recurly__recurly-js": "^4.18",
"@types/redis": "^2.8.32",
"@types/request": "^2.48.7",
"@types/styled-components": "5.1.26",
"@types/webpack": "5.28.0",
"@types/workerpool": "^6.1.0",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"babel-jest": "29.7.0",
"babel-loader": "9.1.3",
"babel-plugin-styled-components": "1.10.7",
"copyfiles": "^2.4.1",
"danger": "^11.3.1",
"danger-plugin-istanbul-coverage": "^1.6.2",
"dotenv": "10.0.0",
"esbuild": "0.19.12",
"esbuild-jest": "^0.5.0",
"eslint": "^8.0.0",
"eslint-config-next": "14.2.3",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-cypress": "^2.10.3",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jest-async": "^1.0.3",
"eslint-plugin-jsx-a11y": "6.10.1",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react-hooks": "5.0.0",
"eslint-plugin-regex": "^1.9.1",
"eslint-plugin-testing-library": "^5.2.1",
"eslint-plugin-unused-imports": "^2.0.0",
"faker": "^5.4.0",
"husky": "^4.3.8",
"jest": "29.7.0",
"jest-bench": "^29.0.0",
"jest-canvas-mock": "^2.3.1",
"jest-environment-jsdom": "29.7.0",
"lint-staged": "^10.5.4",
"moment-timezone": "^0.5.46",
"msw": "^1.2.0",
"nock": "^13.1.1",
"nx": "20.4.2",
"polyrhythm": "^1.2.3",
"prettier": "2.8.8",
"rimraf": "^3.0.2",
"rxjs-marbles": "^7.0.1",
"storybook-addon-apollo-client": "^4.0.9",
"storybook-addon-intl": "^2.4.1",
"ts-jest": "29.1.5",
"ts-node": "^10.9.1",
"tsx": "^4.19.4",
"typescript": "5.7.3",
"typescript-plugin-css-modules": "^5.0.1",
"url-loader": "^4.1.1",
"worker-loader": "^3.0.8"
},
}