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
解决方案
- 给基类方法加空值保护
修改基类的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
- 业务逻辑中处理未登录场景
在实际业务方法中,判断用户是否存在,根据需求返回错误或空结果:
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
- 检查身份验证配置
确保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
相关产品推荐
相关产品推荐

