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

GraphQL中Resolver无法获取Context的问题排查求助

问题描述

在GraphQL的QueryType中使用自定义Resolver:

module Types
  class QueryType < Types::BaseObject
...
    field :gather_things,
          resolver: Resolvers::GatherThings,
          null: true do
      argument :scope, String, required: false
      argument :scope_id, ID, required: false
...

Resolver的基类定义如下:

module Resolvers
  class Base < GraphQL::Schema::Resolver
    def current_user_id
      @current_user_id ||= context[:current_user].id
    end
  end
end

但在子类Resolver中调用current_user_id时触发报错:

module Resolvers
  class GatherThings < Resolvers::Base
...
    def things_resolver(scope, scope_id)
      if scope.nil?
        Thing.from_user(current_user_id)
...
      end
    end
...

报错信息:"undefined method 'id' for nil:NilClass"

原因分析

这个错误的核心是context[:current_user]为nil,直接调用.id方法时触发了空指针异常。可能的具体原因包括:

  • 身份验证中间件未正确配置,导致请求时没有将当前登录用户注入到GraphQL的context中
  • 请求是未登录状态发起的,原本就不存在当前用户,但代码未做空值判断
  • 身份验证逻辑存在bug,比如用户已登录但未被正确写入context
解决方案
  1. 给基类方法加空值保护
    修改基类的current_user_id方法,避免直接对nil调用方法:
module Resolvers
  class Base < GraphQL::Schema::Resolver
    def current_user_id
      return nil unless context[:current_user]
      @current_user_id ||= context[:current_user].id
    end
  end
end
  1. 业务逻辑中处理未登录场景
    在实际业务方法中,判断用户是否存在,根据需求返回错误或空结果:
def things_resolver(scope, scope_id)
  if scope.nil?
    unless current_user_id
      raise GraphQL::ExecutionError, "请先登录"
      # 或者返回空集合:return Thing.none
    end
    Thing.from_user(current_user_id)
  end
  # 其他业务逻辑...
end
  1. 检查身份验证配置
    确保GraphQL控制器中正确将当前用户传入context。以Rails为例,控制器代码应类似:
class GraphqlController < ApplicationController
  def execute
    variables = ensure_hash(params[:variables])
    query = params[:query]
    operation_name = params[:operationName]
    context = {
      current_user: current_user # 确保这里的current_user是通过身份验证框架(如Devise)正确获取的
    }
    result = YourSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
    render json: result
  end

  private

  def ensure_hash(ambiguous_param)
    case ambiguous_param
    when String
      if ambiguous_param.present?
        JSON.parse(ambiguous_param)
      else
        {}
      end
    when Hash, ActionController::Parameters
      ambiguous_param
    when nil
      {}
    else
      raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
    end
  end
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:45:52