Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plug.Conn.Unfetched does not implement the Access behaviour

From the code below, when I call conn.params["geo"], I get the following error:

test/plugs/geoip_test.exs:4
 ** (UndefinedFunctionError) function Plug.Conn.Unfetched.fetch/2 is undefined  (Plug.Conn.Unfetched does not implement the Access behaviour)
 stacktrace:
   (plug) Plug.Conn.Unfetched.fetch(%{:__struct__ => Plug.Conn.Unfetched, :aspect => :params, "geo" => "Mountain View, US", "ip" => "8.8.8.8"}, "geo")

...

defmodule AgilePulse.Plugs.GeoIPTest do
  use AgilePulse.ConnCase

  test "returns Mountain View for 8.8.8.8" do
    conn = build_conn
    params = Map.put(conn.params, "ip", "8.8.8.8")
    conn = Map.put(conn, :params, params) |> AgilePulse.Plugs.GeoIP.call(%{})

    assert conn.params["geo"] == "Mountain View, US"
  end

end

defmodule AgilePulse.Plugs.GeoIP do
  import Plug.Conn

  def init(opts), do: opts

  def call(%Plug.Conn{params: %{"ip" => ip}} = conn, _opts) do
    geo = set_geo(ip)
    params = Map.put(conn.params, "geo", geo)
    Map.put(conn, :params, params)
  end

  def call(conn, _opts), do: conn

  ...

end

Could someone enlighten me on why this is failing and what the appropriate solution is? TY!

like image 685
keruilin Avatar asked Nov 20 '25 08:11

keruilin


1 Answers

Short answer: Change this:

params = Map.put(conn.params, "ip", "8.8.8.8")

To:

params = %{"ip": "8.8.8.8"}

Explanation: Phoenix.ConnTest.build_conn/0 returns a Conn with params set to %Plug.Conn.Unfetched{}. By using Map.put on that, you don't reset the value of __struct__, but only add a new key:

%Plug.Conn{ ...,
 params: %{:__struct__ => Plug.Conn.Unfetched, :aspect => :params,
   "ip" => "8.8.8.8"}, ... }

When you call params["geo"] later, Elixir sees that params is a struct, and tries to call the fetch/2 function on the struct's module, which doesn't exist. To reset params to a normal map (so that Elixir calls Map.get when you use the square bracket syntax), you can just do params = %{"ip": "8.8.8.8"}.

like image 161
Dogbert Avatar answered Nov 23 '25 13:11

Dogbert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!