2017-02-28 10 views
0

Von einem Elixier-Genserver-Prozess aus führe ich die post_metdata-Methode aus, um eine JSON-HTTP-Patch-Anfrage an einen Phoenix-Endpunkt (auf einem anderen Server) zu senden. Der Server fährt mit einem Fehler fort, der anzeigt, dass keine übereinstimmende Klausel, die die JSON-Verbindungsstruktur zeigt, nicht in den Parametern enthalten ist, die auf der Methode basieren. Die ID ist enthalten, aber nicht die übergebene Datennutzlast. Irgendwelche Vorschläge zu was scheint das Problem zu sein?Keine übereinstimmende Aktionsklausel zum Prozess Request-Fehler in HTTPoison.patch

Client-Code

defp post_metadata(metadata, webhook) do 
    case HTTPoison.patch webhook, encode(metadata), [{"content-type", "application/json"}] do 
     {:ok, %HTTPoison.Response{status_code: 200} = response} -> 
     # Logger.debug response.body 
     Logger.debug "Successfully extracted and posted metadata for #{webhook}" 
     {:error, %HTTPoison.Error{reason: reason}} -> 
     Logger.warn "Unable to extract and post metadata for #{webhook}" 
    end 

    end 

    defp encode(metadata) do 
    %{ 
     "link": 
     %{ 
     "title": metadata.title, 
     "description": metadata.description 
     } 
    } 
    |> Poison.encode! 
    end 

Phoenix-Controller-Methode erwartet, aber nicht

def update(conn, %{"id" => id, "link" => link_params}) do 
    link = Repo.get!(Link, id) 
    changeset = Link.changeset(link, link_params) 

    case Repo.update(changeset) do 
     {:ok, link} -> 
     render(conn, "show.json", link: link) 
     {:error, changeset} -> 
     conn 
     |> put_status(:unprocessable_entity) 
     |> render(Mini.ChangesetView, "error.json", changeset: changeset) 
    end 
    end 
abgestimmt ist

router.ex

defmodule Mini.Router do 
    use Mini.Web, :router 

    pipeline :browser do 
    plug :accepts, ["html"] 
    plug :fetch_session 
    plug :fetch_flash 
    plug :protect_from_forgery 
    plug :put_secure_browser_headers 
    end 

    pipeline :api do 
    plug :accepts, ["json"] 
    plug Plug.Logger, log: :debug 
    end 

    scope "/", Mini do 
    pipe_through :browser # Use the default browser stack 

    get "/", PageController, :index 
    end 

    scope "/api", Mini do 
    pipe_through :api 
    resources "/links", LinkController, except: [:new, :edit] 
    end 
end 

Fehler an der Konsole angemeldet

[debug] ** (Phoenix.ActionClauseError) bad request to Mini.LinkController.update, no matching action clause to process request 
    (mini) web/controllers/link_controller.ex:39: Mini.LinkController.update(%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.42492691/1 in Plug.Logger.call/2>, #Function<1.42492691/1 in Plug.Logger.call/2>, #Function<0.111727833/1 in Phoenix.LiveReloader.before_send_inject_reloader/2>], body_params: %{}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "PATCH", owner: #PID<0.438.0>, params: %{"id" => "12"}, path_info: ["api", "links", "12"], path_params: %{}, peer: {{127, 0, 0, 1}, 55369}, port: 4000, private: %{Mini.Router => {[], %{}}, :phoenix_action => :update, :phoenix_controller => Mini.LinkController, :phoenix_endpoint => Mini.Endpoint, :phoenix_format => "json", :phoenix_layout => {Mini.LayoutView, :app}, :phoenix_pipelines => [:api], :phoenix_route => #Function<4.107513407/1 in Mini.Router.match_route/4>, :phoenix_router => Mini.Router, :phoenix_view => Mini.LinkView, :plug_session_fetch => #Function<1.61377594/1 in Plug.Session.fetch_session/1>}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [{"content-type", "application/json, application/json"}, {"user-agent", "hackney/1.6.6"}, {"host", "localhost:4000"}, {"content-length", "58"}], request_path: "/api/links/12", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "5bggaasurlj1oe027nvmv5aiek0hq3k8"}], scheme: :http, script_name: [], secret_key_base: "YfnqjmBhsSJMF/TmhK6qpMnJl7mS0tIYHk1tZ/dZUA6d7KOdv2g/AOJUfWo8sulb", state: :unset, status: nil}, %{"id" => "12"}) 
    (mini) web/controllers/link_controller.ex:1: Mini.LinkController.action/2 
    (mini) web/controllers/link_controller.ex:1: Mini.LinkController.phoenix_controller_pipeline/2 
    (mini) lib/mini/endpoint.ex:1: Mini.Endpoint.instrument/4 
    (mini) lib/phoenix/router.ex:261: Mini.Router.dispatch/2 
    (mini) web/router.ex:1: Mini.Router.do_call/2 
    (mini) lib/mini/endpoint.ex:1: Mini.Endpoint.phoenix_pipeline/1 
    (mini) lib/plug/debugger.ex:123: Mini.Endpoint."call (overridable 3)"/2 
    (mini) lib/mini/endpoint.ex:1: Mini.Endpoint.call/2 
    (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4 
    (cowboy) /Users/billc/dev/mini/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4 

Ich habe eine Anfrage über die JSON-Datenstruktur mit Insomnia mit Erfolg ausgeführt. Ich habe beide Anfragen an Httpbin geschickt und verglichen. Der einzige Unterschied, den ich finden kann, ist der Content-Typ hat doppelte Anwendung/Json Einträge für die Anfrage von HTTPoison gesendet. Aber ich kann keinen Grund oder eine Option zur Vermeidung des doppelten Wertes finden. Es gab auch keinen Grund, warum Phoenix daran ersticken würde.

+0

Ich denke, der ungültige Inhaltstyp verursacht Plug, den Körper nicht zu analysieren, aber ich weiß nicht, warum der Header so gesendet wird. – Dogbert

+0

Ich bin dem Inhaltstyp gleichfalls verdächtig. –

Antwort

0

Aus unerklärlichen Gründen fügt HTTPoison doppelte "application/json" -Werte in den Content-Type-Header ein. Plug ist erstickt auf mehrere Inhaltstyp-Werte. Ich habe das Problem behoben, indem ich ein Semikolon am Ende des übergebenen Headers hinzugefügt habe.

case HTTPoison.patch webhook, encode(metadata), [{"content-type", "application/json;"}] do 

Das abschließende Semikolon beendet den Content-Type-Wert. HTTPoison fügt nur einen einzelnen "application/json" -Wert ein und Plug verhält sich normal.

Seltsam.

+2

Den Fehlerbericht gefunden. Es wurde in hackney 1.7.0 behoben. https://github.com/benoitc/hackney/issues/388 – Dogbert

+0

Ausgezeichnet. Danke, es aufzuspüren! –

Verwandte Themen