代码之家  ›  专栏  ›  技术社区  ›  Junaid Farooq

凤凰灵药中模式匹配异常的处理

  •  0
  • Junaid Farooq  · 技术社区  · 4 年前

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

      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
    

    但它不起作用。

    有可能为整个控制器制造吗?当模式匹配的参数不匹配时,它返回400,同时指出缺少哪些参数?我是唯一一个与头脑中确定的参数相匹配的模式。

    0 回复  |  直到 4 年前
        1
  •  2
  •   Shalaby    4 年前

    是的,有可能使其适用于整个控制器,因为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