graphql icon indicating copy to clipboard operation
graphql copied to clipboard

Mutation with map argument causes KeyError

Open dianjin opened this issue 8 years ago • 0 comments

Hey there, I came across this problem while attempting to issue this mutation via GraphiQL:

mutation M {
  upsertSpread(input: { user_id: 1 }) {
    id
    description
  }
}

My mutation function:

  def mutation do
    %ObjectType{
      name: "mutation",
      fields: %{
        upsertSpread: %{
          type: Spread,
          args: %{
            input: %{ type: SpreadInput }
          },
          resolve: fn(_, args, _) -> TeamBuilder.Data.upsert_spread(args) end
        }
      }
    }
  end

The SpreadInput type:

  defmodule SpreadInput do
    def type do
      %ObjectType{
        name: "SpreadInput",
        fields: %{
          user_id: %{type: %Int{}, description: "user id"}
        }
      }
    end
  end

Stack trace when I issue the mutation in GraphiQL:

Request: POST /graphql/user?query=mutation%20M%20%7B%0A%20%20upsertSpread(input%3A%20%7B%20user_id%3A%201%20%7D)%20%7B%0A%20%20%20%20id%0A%20%20%20%20description%0A%20%20%7D%0A%7D%0A&variables=%7B%0A%20%20%22data%22%3A%20%7B%0A%20%20%20%20%22user_id%22%3A%201%0A%20%20%7D%0A%7D
** (exit) an exception was raised:
    ** (KeyError) key :value not found in: %{fields: [%{kind: :ObjectField, loc: %{start: 0}, name: %{kind: :Name, loc: %{start: 0}, value: "user_id"}, value: %{kind: :IntValue, loc: %{start: 0}, value: 1}}], kind: :ObjectValue, loc: %{start: 0}}
        (graphql) lib/graphql/type/definition.ex:12: GraphQL.Types.Any.parse_literal/2
        (graphql) lib/graphql/execution/executor.ex:255: anonymous fn/4 in GraphQL.Execution.Executor.argument_values/3
        (stdlib) lists.erl:1263: :lists.foldl/3
        (graphql) lib/graphql/execution/executor.ex:138: GraphQL.Execution.Executor.resolve_field/4
        (graphql) lib/graphql/execution/executor.ex:117: anonymous fn/4 in GraphQL.Execution.Executor.execute_fields/4
        (stdlib) lists.erl:1263: :lists.foldl/3
        (graphql) lib/graphql/execution/executor.ex:45: GraphQL.Execution.Executor.execute_operation/3
        (graphql) lib/graphql.ex:106: GraphQL.execute_with_optional_validation/3
        (plug_graphql) lib/graphql/plug/endpoint.ex:85: GraphQL.Plug.Endpoint.execute/2
        (plug_graphql) lib/graphql/plug.ex:54: GraphQL.Plug.call/2
        (hello_graphql) lib/phoenix/router.ex:261: HelloGraphQL.Router.dispatch/2
        (hello_graphql) web/router.ex:1: HelloGraphQL.Router.do_call/2
        (hello_graphql) lib/hello_graphql/endpoint.ex:1: HelloGraphQL.Endpoint.phoenix_pipeline/1
        (hello_graphql) lib/plug/debugger.ex:93: HelloGraphQL.Endpoint."call (overridable 3)"/2
        (hello_graphql) lib/hello_graphql/endpoint.ex:1: HelloGraphQL.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

Everything worked when I issued a mutation with a built-in type like Int or String. Is this the right way to issue a mutation that takes a custom type as an argument? I was under the impression that custom types for mutations should be created with %InputObjectType{} but I got the following error when trying to do that:

== Compilation error on file web/graphql/user_schema.ex ==
** (CompileError) web/graphql/user_schema.ex:8: GraphQL.Type.InputObjectType.__struct__/1 is undefined, cannot expand struct GraphQL.Type.InputObjectType
    web/graphql/user_schema.ex:6: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (stdlib) erl_eval.erl:122: :erl_eval.exprs/5

Thank you!

dianjin avatar Jul 31 '16 05:07 dianjin