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.
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
Ich bin dem Inhaltstyp gleichfalls verdächtig. –