Phoenix - Troubleshooting

The task “” could not be found

$ mix billing --no-brunch
** (Mix) The task "" could not be found


I guess this problem is related to using asdf to manage Elixir versions - Phoenix has not been installed yet into new Elixir directory:

$ mix archive.install
Are you sure you want to install ""? [Yn]
* creating /Users/tap/.asdf/installs/elixir/1.5.1/.mix/archives/phx_new

all styles are gone


I removed priv/static/ directory some time ago - restore it from Git repo or copy from newly generated project:

$ mix hello --no-brunch

connect() failed (111: Connection refused) while connecting to upstream


2018/12/18 11:17:27 [error] 4829#4829: *14 connect() failed (111: Connection refused)
  while connecting to upstream, client: 109.195.XXX.XXX, server: 139.162.XXX.XXX,
  request: "GET /hello HTTP/1.1", upstream: "", host:


  1. Elixir - Deployment

most likely Cowboy is not started:

:server - when true, starts the web server when the endpoint supervision tree starts. Defaults to false. The mix phx.server task automatically sets this to true

  # config/prod.exs

  config :reika, ReikaWeb.Endpoint,
-   load_from_system_env: true,
-   http: [:inet6, port: System.get_env("PORT") || 4000],
-   url: [host: "", port: 80],
+   load_from_system_env: false,
+   http: [port: 4000],
+   url: [host: "139.162.XXX.XXX", port: 80],
+   server: true

corresponding line will appear in systemd journal once Cowboy is started (it will be missing if enpdoint is not configured as described above):

reika[15112]: 11:36:06.017 [info] [swarm on reika@] [tracker:init] started
reika[15112]: 11:36:06.320 [info] Running ReikaWeb.Endpoint with cowboy 2.6.1 at http://139.162.XXX.XXX
reika[15112]: 11:36:11.022 [info] [swarm on reika@] [tracker:cluster_wait] joining cluster..

request body is empty


the problem is that request body is discarded after it’s read and parsed in Plug.Parsers plug so it’s empty in all subsequent plugs:

I need to a way to access the body of a request as a raw string. Plug supports this functionality but as the docs say this can only be done once. Once the body is consumed, trying to read the body will result in an empty string.

but request body is usually required, say, to perform signature verification.



solution added in Plug 1.5.1 is to use custom body reader in Plug.Parsers plug - that reader will cache raw body so that it can be used in subsequent plugs:

# lib/my_app_web/cache_body_reader.ex

defmodule MyAppWeb.CacheBodyReader do
  def read_body(conn, opts) do
    {:ok, body, conn} = Plug.Conn.read_body(conn, opts)
    conn = update_in(conn.assigns[:raw_body], &[body | (&1 || [])])
    {:ok, body, conn}

  def read_cached_body(conn) do
  # lib/my_app_web/endpoint.ex

  plug Plug.Parsers,
    parsers: [:urlencoded, :multipart, :json],
    pass: ["*/*"],
+   body_reader: {MyAppWeb.CacheBodyReader, :read_body, []},
    json_decoder: Phoenix.json_library()

custom plug to perform signature verification:

  # lib/my_app_web/plugs/line/signature_verification.ex

  defmodule MyAppWeb.Plugs.Line.SignatureVerification do
    defp signature(conn) do
-     {:ok, body, conn} = Plug.Conn.read_body(conn)
+     body = MyAppWeb.CacheBodyReader.read_cached_body(conn)

      # ...