NestJS GraphQL查询MongoDB嵌套数据报非空字段null错误
报错根因
你的GraphQL类型定义和实际存储的数据结构存在3处不匹配,导致GraphQL序列化返回数据时触发非空字段校验失败,直接抛错:
- 第一处:
settledTransactions在Socket入参、MongoDB存储、Mongoose Schema里都是数组类型,但你在GraphQL的Settlement ObjectType里把它定义成了单个SettledTransactionsType对象,类型不匹配直接导致序列化失败 - 第二处:嵌套交易对象里的字段名拼写不一致:Mongoose Schema和实际存储的字段名是
transacttransactionTypeionTime,你在GraphQL的SettledTransactionsType里写成了transactionType,GraphQL找不到对应字段,默认非空规则下会判定为null触发报错 - 第三处:所有字段你都没有加
{ nullable: true }配置,而Mongoose Schema里所有字段都设置了required: false,只要某条数据缺任意一个字段,就会触发"非空字段返回null"的错误
修复步骤
1. 修正GraphQL ObjectType定义
把类型不匹配、字段名错误的地方改对,数组类型要显式声明,可选字段配置nullable:
import { ObjectType, Field, Int } from '@nestjs/graphql'; @ObjectType() export class SettledTransactionsType { @Field({ nullable: true }) appName: string; @Field({ nullable: true }) cardInputMethod: string; @Field({ nullable: true }) cardPAN_PCI: string; @Field({ nullable: true }) networkName: string; @Field(() => Int, { nullable: true }) onlineApprovalCode: number; @Field(() => Int, { nullable: true }) onlineRetrievalReferenceNumber: number; @Field(() => Int, { nullable: true }) transactionAmount: number; @Field({ nullable: true }) transactionDate: string; @Field({ nullable: true }) transactionTime: string; // 字段名必须和数据库存储的完全一致,需要别名可单独配置Field映射规则 @Field({ nullable: true }) transacttransactionTypeionTime: string; } @ObjectType() export class Settlement { @Field({ nullable: true }) bReconcileError: boolean; @Field(() => Int, { nullable: true }) batchNumber: number; @Field({ nullable: true }) btransfered: boolean; @Field(() => Int, { nullable: true }) countryCode: number; @Field(() => Int, { nullable: true }) currencyCode: number; @Field({ nullable: true }) merchantID: string; @Field(() => Int, { nullable: true }) nSettlementAmount: number; @Field({ nullable: true }) onlineMessageMACerror: boolean; @Field(() => Int, { nullable: true }) reconciliationAdviceRRN: number; @Field({ nullable: true }) reconciliationApprovalCode: string; // 修正为数组类型声明 @Field(() => [SettledTransactionsType], { nullable: true }) settledTransactions: SettledTransactionsType[]; @Field({ nullable: true }) settlementAmount: string; @Field({ nullable: true }) settlementDate: string; @Field({ nullable: true }) settlementTime: string; @Field({ nullable: true }) terminalID: string; @Field(() => Int, { nullable: true }) traceNumber: number; @Field({ nullable: true }) uniqueID: string; // 补充MongoDB默认返回的_id字段声明 @Field({ nullable: true }) _id: string; }
2. (可选)修正字段拼写错误
你当前存储的transacttransactionTypeionTime属于明显的拼写失误,如果要修正为语义正常的transactionType,需要同步修改四个位置:
- Socket入参接收时的字段映射逻辑
- Mongoose Schema里的对应字段定义
- 历史存量数据的字段名批量更新
- GraphQL类型里的对应字段名
不做修正的话,只要保证GraphQL字段名和数据库存储字段名完全一致,就可以正常返回数据。
3. 校验Resolver返回逻辑
确认findAllSettlement查询对应的Resolver方法,正确返回Mongoose查询结果,不存在漏写return、异常捕获后返回null的问题,参考正确写法:
@Query(() => [Settlement]) async findAllSettlement() { return this.settlementModel.find().exec(); }
验证方式
修改完成后重启NestJS服务,重新发起GraphQL查询,即可正常拿到嵌套的交易列表数据,不会再触发非空字段报错。
内容的提问来源于stack exchange,提问作者Fredrick
相关产品推荐
相关产品推荐

