You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS GraphQL Subscription返回null 报非空字段不可为null错误

NestJS GraphQL Subscription 报错 Cannot return null for non-nullable field Subscription 排查与修复

问题场景

使用NestJS + GraphQL开发项目,测试Subscription基础功能时触发报错:
Cannot return null for non-nullable field Subscription.orderSubscription


复现信息

  • 业务层基础订阅发布测试代码:
//* ~~~~~~~~~~~~~~~~~~~ Subscription ~~~~~~~~~~~~~~~~~~~ */
@Mutation((returns) => Boolean)
testSubscription() {
  pubsub.publish('somethingOnTrack', {
    somethingOnTrack: 'something',
  });
  return true;
}
@Subscription((returns) => String)
orderSubscription() {
  return pubsub.asyncIterator('somethingOnTrack');
}
  • GraphQL模块配置(同时启用两种WebSocket订阅实现):
GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
  subscriptions: {
    'graphql-ws': true,
    'subscriptions-transport-ws': true,
  },
}),
  • 测试操作流程:

    1. 先在GraphQL Playground发起订阅请求:
    subscription {
      orderSubscription
    }
    
    1. 再触发对应mutation:
    mutation {
      testSubscription
    }
    
  • 实际运行结果:

    • Mutation正常返回预期结果:
    {
      "data": {
        "testSubscription": true
      }
    }
    
    • Subscription端返回错误:
    {
      "errors": [
        {
          "message": "Cannot return null for non-nullable field Subscription.orderSubscription.",
          "locations": [
            {
              "line": 2,
              "column": 3
            }
          ],
          "path": [
            "orderSubscription"
          ]
        }
      ],
      "data": null
    }
    

错误原因

NestJS GraphQL的Subscription默认解析逻辑为:从pubsub推送的payload对象中,读取与订阅方法同名的顶层字段作为返回值。
上述代码中订阅方法名为orderSubscription,但pubsub.publish推送的payload顶层只有somethingOnTrack字段,没有匹配的orderSubscription字段,解析得到的值为undefined。而自动生成的Schema中该字段为非空String类型,因此触发"非空字段返回null"的校验错误。


修复方案

两种方案二选一即可:

  1. 统一publish的payload字段名与订阅方法名
    修改mutation中publish的payload,将顶层key改为和订阅方法一致:
@Mutation((returns) => Boolean)
testSubscription() {
  pubsub.publish('somethingOnTrack', {
    // 字段名和@Subscription装饰的方法名保持一致
    orderSubscription: 'something',
  });
  return true;
}
  1. 自定义Subscription的resolve逻辑,手动指定返回值
    给@Subscription装饰器传入resolve配置,手动从payload中取出需要返回的字段,无需修改publish逻辑:
@Subscription((returns) => String, {
  resolve: (payload) => payload.somethingOnTrack
})
orderSubscription() {
  return pubsub.asyncIterator('somethingOnTrack');
}

补充说明:同时启用graphql-ws和subscriptions-transport-ws不会直接导致该错误,但生产环境建议根据客户端使用的协议只保留对应实现,避免不必要的连接冲突。


内容的提问来源于stack exchange,提问作者Yue Dong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:54:28