Phoenix.Router.NoRouteError - no route found for GET /uploads/image.png

I am doing the course of the pragprog (Chapter 27 - File Uploads: Server) for upload a image.
And this is the code for save the files.

def handle_event("save", %{"desk" => params}, socket) do
    # copy temp file to priv/static/uploads/abc-1.png
    # URL path: /uploads/abc-1.png

    photo_locations =
      consume_uploaded_entries(socket, :photos, fn meta, entry ->
        dest =
          Path.join([
            "priv",
            "static",
            "uploads",
            "#{entry.uuid}-#{entry.client_name}"
          ])

        File.cp!(meta.path, dest)

        url_path = static_path(socket, "/uploads/#{Path.basename(dest)}")

        {:ok, url_path}
      end)

    params = Map.put(params, "photo_locations", photo_locations)

    case Desks.create_desk(params) do
      {:ok, _desk} ->
        changeset = Desks.change_desk(%Desk{})
        {:noreply, assign_form(socket, changeset)}

      {:error, %Ecto.Changeset{} = changeset} ->
        {:noreply, assign_form(socket, changeset)}
    end
  end

Before it was having an error with the File.cp!
But I created the folder uploads on the priv/static/uploads and then it uploads the file.
But it isn’t showing the images.
And It’s complaining for this:

[info] GET /uploads/fe150541-27f5-4fc2-86f2-394c5b1b4df3-bingo01.jpg
[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /uploads/fe150541-27f5-4fc2-86f2-394c5b1b4df3-bingo01.jpg (RldLiveViewStudioWeb.Router)
    (rld_live_view_studio 0.1.0) lib/phoenix/router.ex:487: RldLiveViewStudioWeb.Router.call/2
    (rld_live_view_studio 0.1.0) lib/rld_live_view_studio_web/endpoint.ex:1: RldLiveViewStudioWeb.Endpoint.plug_builder_call/2
    (rld_live_view_studio 0.1.0) lib/plug/debugger.ex:136: RldLiveViewStudioWeb.Endpoint."call (overridable 3)"/2
    (rld_live_view_studio 0.1.0) lib/rld_live_view_studio_web/endpoint.ex:1: RldLiveViewStudioWeb.Endpoint.call/2
    (phoenix 1.7.2) lib/phoenix/endpoint/sync_code_reload_plug.ex:22: Phoenix.Endpoint.SyncCodeReloadPlug.do_call/4
    (plug_cowboy 2.6.1) lib/plug/cowboy/handler.ex:11: Plug.Cowboy.Handler.init/2
    (cowboy 2.10.0) /Users/romenigld/workspace/phoenix/phoenix_live_view/pragprog/phoenix-liveview-2nd-course/rld_code/rld_live_view_studio/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
    (cowboy 2.10.0) /Users/romenigld/workspace/phoenix/phoenix_live_view/pragprog/phoenix-liveview-2nd-course/rld_code/rld_live_view_studio/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
    (cowboy 2.10.0) /Users/romenigld/workspace/phoenix/phoenix_live_view/pragprog/phoenix-liveview-2nd-course/rld_code/rld_live_view_studio/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
    (stdlib 4.2) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

So, I was thinking it was some configuration of the uploads folder and I add this which I copied from the video code of the course on the file config/dev.exs:

config :rld_live_view_studio, RldLiveViewStudioWeb.Endpoint,
  live_reload: [
    patterns: [
      ~r"priv/static/(?!uploads).*(js|css|png|jpeg|jpg|gif|svg)$",
      ~r"priv/gettext/.*(po)$",
      ~r"lib/rld_live_view_studio_web/(controllers|live|components)/.*(ex|heex)$"
    ]
  ]

But the error persists:

[info] GET /uploads/fe150541-27f5-4fc2-86f2-394c5b1b4df3-bingo01.jpg
[info] GET /uploads/18d33968-79f6-4f03-b451-790df5894de1-romenig%20surf.jpeg
[info] GET /uploads/24933b6e-0046-4b2a-987b-ba87ffca6e10-romenig%20surf.jpeg
[info] GET /uploads/e52d806f-62f2-47c4-9f6c-f857cf2f78bf-Screenshot_20230314-083711.png
[info] GET /uploads/1e6e8af7-cf2c-408a-a6f4-53893f806a9b-bingo01.jpg
[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /uploads/24933b6e-0046-4b2a-987b-ba87ffca6e10-romenig%20surf.jpeg (RldLiveViewStudioWeb.Router)
    (rld_live_view_studio 0.1.0) lib/phoenix/router.ex:487: RldLiveViewStudioWeb.Router.call/2
    (rld_live_view_studio 0.1.0) lib/rld_live_view_studio_web/endpoint.ex:1: RldLiveViewStudioWeb.Endpoint.plug_builder_call/2
    (rld_live_view_studio 0.1.0) lib/plug/debugger.ex:136: RldLiveViewStudioWeb.Endpoint."call (overridable 3)"/2
    (rld_live_view_studio 0.1.0) lib/rld_live_view_studio_web/endpoint.ex:1: RldLiveViewStudioWeb.Endpoint.call/2
    (phoenix 1.7.2) lib/phoenix/endpoint/sync_code_reload_plug.ex:22: Phoenix.Endpoint.SyncCodeReloadPlug.do_call/4
    (plug_cowboy 2.6.1) lib/plug/cowboy/handler.ex:11: Plug.Cowboy.Handler.init/2
    (cowboy 2.10.0) /Users/romenigld/workspace/phoenix/phoenix_live_view/pragprog/phoenix-liveview-2nd-course/rld_code/rld_live_view_studio/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
    (cowboy 2.10.0) /Users/romenigld/workspace/phoenix/phoenix_live_view/pragprog/phoenix-liveview-2nd-course/rld_code/rld_live_view_studio/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
    (cowboy 2.10.0) /Users/romenigld/workspace/phoenix/phoenix_live_view/pragprog/phoenix-liveview-2nd-course/rld_code/rld_live_view_studio/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
    (stdlib 4.2) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

You need to add uploads to the static_paths function which can be found in your lib/my_app_web.ex. I agree that this feels like it belongs in config as it seems like the more natural place to look. Although, when dealing with HTTP stuff, I would always look at MyAppWeb.Endpoint as it’s the entry point so it’s sorta the best place to orient yourself when trying to figure this stuff out.

Now it shows,
so It is needed to erase the uploads configuration on the config/dev.exs?

~r"priv/static/(?!uploads).*(js|css|png|jpeg|jpg|gif|svg)$",

Thank you @sodapopcan!

1 Like

Oh right! Yes, I wouldn’t bother putting that there. That config is all about live reload which is the development tool that reloads the browser when stuff in those paths change. If you leave in there then the browser will reload as soon as you upload something which is probably not what you want.

Yes, I quit this, and it is working as I desire, thank you again!

1 Like

Hello,
If it helps (especially for beginners), here’s an example :slight_smile:

def static_paths, do: ~w(assets fonts uploads images favicon.ico robots.txt)

1 Like