EDIT: You can skip to the end for a simplified example of the error in codesandbox
I'm upgrading my apollo project to the new version of graphql and I'm getting a weird error. Can't find any results that match this scenario on google. When I attempt to return an empty array of ObjectTypes DrivingActivitiesDailySummaryType that have non-nullable fields (including day), it throws a "Cannot return null for non-nullable field DrivingActivitiesDailySummaryType.day.". This worked as intended in version 14.7.0. What's happening here? How to avoid it? I would think that the normal behavior would be to allow empty arrays and I can't find anything in the changelog that would indicate a change of this type.
My resolver currently just returns a hardcoded value for testing:
@Query(() => DrivingActivityPayload)
public async totalDrivingActivity(
@Ctx("user") userContext: UserContext,
@Args() input: DrivingActivitiesQueryInput
): Promise<DrivingActivityPayload> {
return {
totalSummary: { speed: 1, activities: 1, duration: 1, distance: 1 },
dailySummaries: [],
monthlySummaries: [],
}
}
My payload deffinition:
@ObjectType()
export class DrivingActivityPayload {
@Field(() => DrivingActivitiesTotalSummaryType)
public totalSummary: DrivingActivitiesTotalSummaryType
@Field(() => DrivingActivitiesDailySummaryType)
public dailySummaries: DrivingActivitiesDailySummaryType[]
@Field(() => DrivingActivitiesMonthlySummaryType)
public monthlySummaries: DrivingActivitiesMonthlySummaryType[]
constructor(
totalSummary: DrivingActivitiesTotalSummaryType,
dailySummaries: DrivingActivitiesDailySummaryType[],
monthlySummaries: DrivingActivitiesMonthlySummaryType[]
) {
this.totalSummary = new DrivingActivitiesTotalSummaryType(totalSummary)
this.dailySummaries = dailySummaries.map(summary => new DrivingActivitiesDailySummaryType(summary))
this.monthlySummaries = monthlySummaries.map(summary => new DrivingActivitiesMonthlySummaryType(summary))
}
}
The GraphQL error:
"errors": [
{
"message": "Cannot return null for non-nullable field DrivingActivitiesDailySummaryType.day.",
"locations": [
{
"line": 18,
"column": 7
}
],
"path": [
"totalDrivingActivity",
"dailySummaries",
"day"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: Cannot return null for non-nullable field DrivingActivitiesDailySummaryType.day.",
" at completeValue ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:559:13)",
" at resolveField ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:472:19)",
" at executeFields ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:292:18)",
" at collectAndExecuteSubfields ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:748:10)",
" at completeObjectValue ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:738:10)",
" at completeValue ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:590:12)",
" at completeValue ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:556:21)",
" at resolveField ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:472:19)",
" at executeFields ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:292:18)",
" at collectAndExecuteSubfields ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:748:10)",
" at completeObjectValue ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:738:10)",
" at completeValue ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:590:12)",
" at completeValue ([PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:556:21)",
" at [PROJECT-FOLDER]/node_modules/graphql/execution/execute.js:469:16",
" at processTicksAndRejections (node:internal/process/task_queues:96:5)",
" at async Promise.all (index 0)"
]
}
}
}
],
"data": null
}
The DrivingActivitiesDailySummaryType deffinition (though this shouldn't matter):
@ObjectType()
export class DrivingActivitiesDailySummaryType {
@Field(() => Date)
public day: Date
@Field()
public distance: number
@Field()
public activities: number
constructor(summary: DrivingActivitiesDailySummaryType) {
this.day = summary.day
this.activities = summary.activities
this.distance = summary.distance
}
}
Edit: Here's a sandbox link with the reproduced error: https://codesandbox.io/s/heuristic-jepsen-5frr3?file=/package.json (I didn't know how to change the default terminal behaviour so you'll have to open a new terminal with the "+" icon and run "npm start") When using the provided package.json (with new versions) the error is reproduced, when you switch the contents of package.json with package-old.json (older versions of graphql and type-graphql) there is no error.
EDIT2: You will probably need to add "/graphql" to the codesandbox link for it to work
You should define daily and monthly summaries as array:
@Field(() => [DrivingActivitiesDailySummaryType])
public dailySummaries: DrivingActivitiesDailySummaryType[]
@Field(() => [DrivingActivitiesMonthlySummaryType])
public monthlySummaries: DrivingActivitiesMonthlySummaryType[]