malomohq/shopify-graphql-elixir

Jason attempting to decode a map raises an exception

aalfson opened this issue · 4 comments

I want to start off by saying thank you for open sourcing this library. It's been really helpful :)

We're encountering an issue in production with 2.0-rc3 where the response body has already been decoded and Jason is raising an exception. I've included the stack trace below. I can't reproduce it in development, but it pops up pretty regularly in production. I haven't been able to figure out why the response body has already been decoded.

|> config.json_codec.decode!()

I submitted a PR that bandaids the issue, but doesn't get to the root cause. I'd be happy to update my PR if you have some ideas on what the root cause might be.

* (ArgumentError) argument error
    :erlang.iolist_to_binary(%{"data" => %{"product" => %{"id" => "gid://shopify/Product/PRODUCT_ID", "totalVariants" => 30}}, "extensions" => %{"cost" => %{"actualQueryCost" => 1, "requestedQueryCost" => 1, "throttleStatus" => %{"currentlyAvailable" => 999, "maximumAvailable" => 1.0e3, "restoreRate" => 50.0}}}})
    (jason 1.2.2) lib/jason.ex:55: Jason.decode/2
    (jason 1.2.2) lib/jason.ex:76: Jason.decode!/2
    (shopify_graphql 2.0.0-rc.3) lib/shopify/graphql/response.ex:18: Shopify.GraphQL.Response.new/2
    (shopify_graphql 2.0.0-rc.3) lib/shopify/graphql/request.ex:97: Shopify.GraphQL.Request.finish/2
    (shopify_graphql 2.0.0-rc.3) lib/shopify/graphql/limiter/consumer.ex:20: Shopify.GraphQL.Limiter.Consumer.send/1
    (elixir 1.11.2) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
    (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Function: &Shopify.GraphQL.Limiter.Consumer.send/1
    Args: [%{config: %Shopify.GraphQL.Config{access_token: "*****************************", endpoint: "/graphql.json", http_client: Shopify.GraphQL.Http.Hackney, http_client_opts: [timeout: 150000, max_connections: 500, recv_timeout: 30000, ssl_options: [versions: [:"tlsv1.2"]]], http_headers: [], http_host: "myshopify.com", http_path: "/admin/api", http_port: nil, http_protocol: "https", json_codec: Jason, limiter: true, limiter_opts: [monitor: true], retry: Shopify.GraphQL.Retry.Linear, retry_opts: [max_attempts: 3], shop: "shop_name", version: "2021-01"}, limiter_opts: [monitor: true], owner: {#PID<0.4108.2>, #Reference<0.879404005.3716677635.179382>}, partition: :"Elixir.Shopify.GraphQL.Limiter.Partition:shop_name.myshopify.com", request: %Shopify.GraphQL.Request{body: "{\"query\":\"query {\\n  product(id: \\\"gid://shopify/Product/PRODUCT_ID\\\") {\\n    id\\n    totalVariants\\n  }\\n}\\n\",\"variables\":{}}", config: %Shopify.GraphQL.Config{access_token: "*****************************", endpoint: "/graphql.json", http_client: Shopify.GraphQL.Http.Hackney, http_client_opts: [timeout: 150000, max_connections: 500, recv_timeout: 30000, ssl_options: [versions: [:"tlsv1.2"]]], http_headers: [], http_host: "myshopify.com", http_path: "/admin/api", http_port: nil, http_protocol: "https", json_codec: Jason, limiter: true, limiter_opts: [monitor: true], retry: Shopify.GraphQL.Retry.Linear, retry_opts: [max_attempts: 3], shop: "shop_name", version: "2021-01"}, headers: [{"content-type", "application/json"}, {"x-shopify-access-token", "*****************************"}], method: :post, private: %{}, url: "https://shop_name.myshopify.com/admin/api/2021-01/graphql.json"}}]

Thank you for reporting!

Do you have retries enabled? I think that might be culprit.

I don't think I'm adequately testing the retry code so I'm going to refactor that and see if I can find the issue.

I was able to create a test to reproduce this. A fix is in master. I'll get a new release out asap.

This should be fixed in 2.0.0-rc.4.

Thanks!