Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't unshim middleware if they aren't shimmed to begin with #94

Merged
merged 2 commits into from
Apr 11, 2024

Conversation

jeffutter
Copy link
Contributor

Hi there, this PR fixes an issue we were seeing when deployed in an application. I apologize for the lack of tests, but I'm not entirely sure why this error is happening or how to trigger it in tests. I wrote a few tests but they all pass regardless of the change.

Error

We're trying to support "Entity Queries" on an Interface, this is the "receiving end" of the @interfaceObject directive.

Our schema looks roughly like this:

defmodule SchemaWithEntityInterface do
  use Absinthe.Schema
  use Absinthe.Federation.Schema

  query do
    field :named_entity, :named_entity
  end

  interface :named_entity do
    key_fields("name")

    field :name, :string

    resolve_type fn
      %{age: _}, _ -> :person
      %{employee_count: _}, _ -> :business
      _, _ -> nil
    end

    field :_resolve_reference, :named_entity do
      resolve(fn
        _, %{name: "John"}, _ ->
          {:ok, %{__typename: "Person", name: "John", age: 20}}

        _, %{name: "Acme"}, _ ->
          {:ok, %{__typename: "Business", name: "Acme", employee_count: 10}}
      end)
    end
  end

  object :person do
    key_fields("name")

    import_fields(:named_entity, [:name, :_resolve_reference])
    field :age, :integer

    interface :named_entity
  end

  object :business do
    key_fields("name")

    import_fields(:named_entity, [:name, :_resolve_reference])
    field :employee_count, :integer

    interface :named_entity
  end
end

When writing unit tests setup like this in absinthe_federation it works fine. In our application either in tests or deployed I get the following error. I haven't been able to simplify it enough to figure out the difference between running in my application vs. in absinthe_federation unit tests.

#PID<0.78989.0> running MyAppWeb.Endpoint (connection #PID<0.78988.0>, stream id 1) terminated
Server: myapp.com:80 (http)
Request: POST /graphql
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in Absinthe.Middleware.unshim/2
        (absinthe 1.7.6) lib/absinthe/middleware.ex:279: Absinthe.Middleware.unshim([{Absinthe.Middleware.Telemetry, []}, {{Absinthe.Resolution, :call}, #Function<1.131082921/3 in MyAppWeb.Schema.Types.InterfaceEntity.__absinthe_function__/2>}], LiveWeb.Schema)
        (absinthe_federation 0.5.0) lib/absinthe/federation/schema/entities_field.ex:176: Absinthe.Federation.Schema.EntitiesField.resolve_reference/4
        (absinthe_federation 0.5.0) lib/absinthe/federation/schema/entities_field.ex:140: Absinthe.Federation.Schema.EntitiesField.entity_accumulator/3
        (elixir 1.16.0) lib/enum.ex:1700: Enum."-map/2-lists^map/1-1-"/2
        (absinthe_federation 0.5.0) lib/absinthe/federation/schema/entities_field.ex:86: Absinthe.Federation.Schema.EntitiesField.call/2
        (absinthe 1.7.6) lib/absinthe/phase/document/execution/resolution.ex:234: Absinthe.Phase.Document.Execution.Resolution.reduce_resolution/1
        (absinthe 1.7.6) lib/absinthe/phase/document/execution/resolution.ex:189: Absinthe.Phase.Document.Execution.Resolution.do_resolve_field/3
        (absinthe 1.7.6) lib/absinthe/phase/document/execution/resolution.ex:174: Absinthe.Phase.Document.Execution.Resolution.do_resolve_fields/6

PR

Hopefully, this PR makes sense as-is and is useful. If someone can help me better understand how a middleware gets shimmed and why absinthe_federation has to call the (seemingly private) unshim function. I'd be glad to contribute a more thorough solution with tests.

@kzlsakal
Copy link
Collaborator

Hi @jeffutter, thank you for the PR! I used your sample schema in one of my local projects that uses multiple middleware, but I wasn't able to reproduce the error you mentioned. What does the query body look like when you get this error?

@kdawgwilk calling the expert here; do you have any suggestions about how we can go about testing this?

@jeffutter
Copy link
Contributor Author

Hey. Thanks for the quick response!

The query looks something like this:

query {
  _entities(representations: [{__typename: "NamedEntity", name: "John"}]) {
    ... on NamedEntity {
      name
      ... on Person {
        age
      }
    }
  }
}

I'm pretty stumped as to how our application is different than what I can write in unit tests. My best guess is we're adding a middleware somewhere that somehow messes with the shim stuff.

@kzlsakal
Copy link
Collaborator

kzlsakal commented Apr 10, 2024

Hmm I am getting the following response for that with the schema you posted, and no errors:

{
    "data": {
        "_entities": [
            {
                "age": 20,
                "name": "John"
            }
        ]
    }
}

What absinthe/absinthe_federation/elixir versions are you on?

@jeffutter
Copy link
Contributor Author

@kzlsakal I figured it out! :-D

It happens on Schemas with @schema_provider Absinthe.Schema.PersistentTerm. I've included a failing test that is fixed with the change I made.

Perhaps there's a better way to address it though?

Copy link
Collaborator

@kzlsakal kzlsakal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kzlsakal I figured it out! :-D

It happens on Schemas with @schema_provider Absinthe.Schema.PersistentTerm. I've included a failing test that is fixed with the change I made.

Perhaps there's a better way to address it though?

Brilliant! Thanks for uncovering this issue. I requested a couple of nitty changes, otherwise it looks great!

lib/absinthe/federation/schema/entities_field.ex Outdated Show resolved Hide resolved
test/absinthe/federation/schema/entities_field_test.exs Outdated Show resolved Hide resolved
@kzlsakal kzlsakal added the bug Something isn't working label Apr 11, 2024
@jeffutter
Copy link
Contributor Author

@kzlsakal Should be all tidied up now. Let me know if there's anything else that needs to be changed. Thanks!

@jeffutter jeffutter requested a review from kzlsakal April 11, 2024 15:40
Copy link
Collaborator

@kzlsakal kzlsakal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @jeffutter!

@kzlsakal kzlsakal merged commit 4125eaa into DivvyPayHQ:main Apr 11, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants