← 中文资源

简体中文版本

GraphQL 非空字段返回 null — 错误向上传播

通过找出返回 null 的解析器、追踪错误传播,并对齐 schema 可空性,修复“非空字段不能返回 null”。

阅读英文原文

症状

错误“GraphQL 非空字段返回 null — 错误向上传播”指向一个明确的失效模式。下面依次给出症状、定位该原因的检查命令、根本原因、修复方案,以及证明修复有效的验证步骤。

可观察到的症状包括:

  • 响应包含 “Cannot return null for non-nullable field User.name”
  • 一个字段失败导致整个父对象变为 null
  • 客户端收到部分为 null 的响应并带 errors

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

curl -s -X POST https://api.example.com/graphql -H 'Content-Type: application/json' -d '{"query":"{ user { name } }"}'

错误路径会指出返回 null 的确切字段解析器。

步骤 2

git grep -n "User:\|name:" src/graphql/resolvers

在解析器内记录可确认是返回 null 还是抛错。

常见诱因(按出现频率排序):

  • 解析器对 schema 中声明为非空的字段返回 null
  • 异步解析器拒绝,错误越过了非空边界向上传播
  • 数据源确实缺失该值,而 schema 却标为非空

根因

GraphQL 会沿非空字段向上传播 null:若非空字段解析为 null,错误会冒泡到最近的可空父级并使其为 null。这可保护客户端免于不完整对象,但可能置空的范围超出预期。

修复

修正解析器返回非空值,把确实可选的字段在 schema 中改为可空,并在解析器内处理错误,避免单个失败置空整个父级。

注意:为规避错误而把字段改为可空会把 null 处理推给每个客户端;值必需时应修正数据或解析器。

type User {
  id: ID!
  name: String!      # non-null: resolver must never return null
  bio: String        # nullable: may be absent
}

// resolver: satisfy the non-null contract or throw a field error
User: {
  name: (u) => {
    if (!u.name) throw new Error('User.name is required');
    return u.name;
  },
}

验证

重跑查询并确认字段有值且 errors 为空;验证真实失败仍给出清晰错误。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。