处理 phoenix elixir 中的模式匹配异常

handling pattern match exceptions in phoenix elixir

我有多个控制器方法,我在其中与即将到来的参数进行模式匹配,其中之一是

  def index(conn, %{
        "id" => camera_exid,
        "from" => from,
        "to" => to,
        "limit" => "3600",
        "page" => _page
      }) do

当用户请求时 http://localhost:4000/v2/cameras/pocri-yweod/recordings/snapshots?limit=3600&page=1

它会抛出一个错误,当然,它应该是通过错误来处理的,但是有没有比异常更优雅地处理这种错误的方法呢?没有创建另一个具有更少值的索引来进行模式匹配?

我尝试创建一个非常基础的后备控制器

defmodule EvercamMediaWeb.FallbackController do
  use EvercamMediaWeb, :controller

  def call(conn, what) do
    IO.inspect(what)
    render_error(conn, 400, "error.")
  end
end

但是没用。

是否可以为整个控制器制作它?当模式匹配的参数不匹配时,它 returns 400 同时说缺少哪些参数?我是唯一匹配头部参数的模式。

是的,可以为整个控制器创建它,因为 phoenix 在控制器中注入了一个 action/2 插件,该插件在默认情况下会调用与路由器匹配的功能,并且它可以被覆盖。

在你的控制器中试试这个:

  def action(conn, _) do
    required_fields = %{
      index: ["id", "from", "to", "limit", "page"],
      action2: ["id", "x", "y"]
    }

    args = [conn, conn.params]

    missing_fields =
      Enum.reject(required_fields[action_name(conn)], fn x -> x in Map.keys(conn.params) end)

    case missing_fields do
      [] ->
        apply(__MODULE__, action_name(conn), args)

      fields ->
        conn
        |> put_status(:bad_request)
        |> text("missing fields: " <> inspect(fields))
    end
  end

如果 missing_fields 列表不为空,您可以按照自己喜欢的方式呈现。

ps:返回错误 400 不是异常,这是一个处理得很好的错误,正如 Jose 在此处所说 https://github.com/phoenixframework/phoenix/issues/2386#issuecomment-315590839