Skip to content

Incorrect handling of enum input value coercions #5499

@gmac

Description

@gmac

Describe the bug

Input coercion errors raised by leaf types are pretty spotty on validating correctly. I've included a complete test suite below, but the summary is:

  • Enum types don't call coerce_input during validation. Therefore, the query is incorrectly valid, this input does not block execution, and the error manifests as a field execution error. Right error, wrong time.
  • Scalars DO call coerce_input, and will statically invalidate the query to prevent it from executing. When this happens via variables, we get a good error message. When it happens via AST, not so much.
class GraphQLRubyTest < Minitest::Test
  class TestSchema < GraphQL::Schema
    class MyScalar < GraphQL::Schema::Scalar
      def self.coerce_input(value, ctx = nil)
        raise GraphQL::ExecutionError.new("boom")
      end
    end

    class MyEnum < GraphQL::Schema::Enum
      def self.coerce_input(value, ctx = nil)
        raise GraphQL::ExecutionError.new("boom")
      end

      value "BOOM"
    end

    class Query < GraphQL::Schema::Object
      field :scalar, String do |f|
        f.argument :input, MyScalar, required: true
      end

      field :enum, String do |f|
        f.argument :input, MyEnum, required: true
      end
    end

    query(Query)
  end

  def test_reports_validation_errors_with_scalar_ast
    query = ::GraphQL::Query.new(TestSchema, "{ scalar(input: 1) }")
    query.result.to_h

    # This is sort of the right error, but is missing a bunch of relevant information
    # {"errors" => [{"message" => "boom"}]}

    # This works...
    refute query.valid?
  end

  def test_reports_validation_errors_with_scalar_variables
    query = ::GraphQL::Query.new(TestSchema, "query($input: MyScalar!) { scalar(input: $input) }", variables: { input: 1 })
    query.result.to_h

    # This is the correct error
    # {"errors" => [{
    #   "message" => "Variable $input of type MyScalar! was provided invalid value",
    #   "locations" => [{"line" => 1, "column" => 7}],
    #   "extensions" => {"value" => 1, "problems" => [{"path" => [], "explanation" => "boom"}]},
    # }]}

    # This works...
    refute query.valid?
  end

  def test_reports_validation_errors_with_enums_ast
    query = ::GraphQL::Query.new(TestSchema, "{ enum(input: BOOM) }")
    query.result.to_h

    # This is a field execution error, it should have been a variable error that blocked execution
    # {"errors" => [{"message" => "boom", "locations" => [{"line" => 1, "column" => 3}], "path" => ["enum"]}], "data" => {"enum" => nil}}

    # This fails... query is valid?
    refute query.valid?
  end

  def test_reports_validation_errors_with_enum_variables
    query = ::GraphQL::Query.new(TestSchema, "query($input: MyEnum!) { enum(input: $input) }", variables: { input: "BOOM" })
    query.result.to_h

    # This is a field execution error, it should have been a variable error that blocked execution
    # {"errors" => [{"message" => "boom", "locations" => [{"line" => 1, "column" => 26}], "path" => ["enum"]}], "data" => {"enum" => nil}}

    # This fails... query is valid?
    refute query.valid?
  end
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions