在 Elixir 中编写以下逻辑的惯用方法是什么?
What is the idiomatic way to write the following logic in Elixir?
我有一个端点 check
如果请求包含有效 auth_token
则 returns 响应 200
否则 401
。
def check(conn, _) do
if auth_token = get_session(conn, :auth_token) do
send_resp(conn, 200, "")
end
send_resp(conn, 401, "")
end
这在 auth_token
为 nil
的情况下工作正常,但是,对于定义它的情况,我遇到了一个奇怪的错误。
[error] Ranch listener AppWeb.Endpoint.HTTP had connection process started with :cowboy_clear:start_link/4 at #PID<0.6370.0> exit with reason: {:function_clause, [{:cowboy_http, :commands, [{:state, #PID<0.5887.0>, AppWeb.Endpoint.HTTP, #Port<0.1651>, :ranch_tcp, :undefined, %{env: %{dispatch: [{:_, [], [{:_, [], Phoenix.Endpoint.Cowboy2Handler, {AppWeb.Endpoint, []}}]}]}, stream_handlers: [Plug.Cowboy.Stream]}, "", %{}, {{127, 0, 0, 1}, 61063}, {{127, 0, 0, 1}, 4000}, :undefined, #Reference<0.3022468478.150208513.95764>, true, 2, {:ps_request_line, 0}, 65535, 1, :done, 1000, [{:stream, 1, {Plug.Cowboy.Stream, {:state, :undefined, AppWeb.Endpoint.HTTP, #PID<0.6371.0>, :undefined, :undefined, :undefined, :undefined, 0, :nofin, "", 0, :undefined, :normal}}, "GET", :"HTTP/1.1", :undefined, :undefined, 0, []}], [{:child, #PID<0.6371.0>, 1, 5000, :undefined}]}, 1, [{:response, "401 Unauthorized", %{"cache-control" => "max-age=0, private, must-revalidate", "content-length" => "0", "date" => "Sat, 29 Aug 2020 17:32:18 GMT", "server" => "Cowboy", "x-request-id" => "Fi_Nf1nWhRxOi1UAAQPB"}, ""}]], [file: '/Users/raph/Code/App/api/deps/cowboy/src/cowboy_http.erl', line: 954]}, {:cowboy_http, :loop, 1, [file: '/Users/raph/Code/App/api/deps/cowboy/src/cowboy_http.erl', line: 254]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}
注意:所有情况下响应发送成功,之后出现上述错误。
错误是什么意思,我该如何避免?
更新
我刚刚注意到上面的代码似乎试图发送两个响应:
[info] Sent 200 in 41ms
[info] Sent 401 in 41ms
鉴于我的真实代码更接近于:
def check(conn, _) do
if auth_token = get_session(conn, :auth_token) do
if user = Accounts.get_user_by_session_token(auth_token) do
send_resp(conn, 200, Map.get(user, :email))
end
end
send_resp(conn, 401, "")
end
编写上述逻辑的惯用方法是什么 send_resp
只被调用一次?
下面的实现没有错误,但感觉可以用更惯用的方式重构它。
def check(conn, _) do
if auth_token = get_session(conn, :auth_token) do
if user = Accounts.get_user_by_session_token(auth_token) do
send_resp(conn, 200, Map.get(user, :email))
else
send_resp(conn, 401, "")
end
else
send_resp(conn, 401, "")
end
end
假设有一个 User
结构,我认为这更符合习惯:
def check(conn, _) do
with token when is_binary(token) <- get_session(conn, :auth_token),
%User{} = user <- Accounts.get_user_by_session_token(token) do
send_resp(conn, 200, user.email)
else
_ -> send_resp(conn, 401, "")
end
end
我有一个端点 check
如果请求包含有效 auth_token
则 returns 响应 200
否则 401
。
def check(conn, _) do
if auth_token = get_session(conn, :auth_token) do
send_resp(conn, 200, "")
end
send_resp(conn, 401, "")
end
这在 auth_token
为 nil
的情况下工作正常,但是,对于定义它的情况,我遇到了一个奇怪的错误。
[error] Ranch listener AppWeb.Endpoint.HTTP had connection process started with :cowboy_clear:start_link/4 at #PID<0.6370.0> exit with reason: {:function_clause, [{:cowboy_http, :commands, [{:state, #PID<0.5887.0>, AppWeb.Endpoint.HTTP, #Port<0.1651>, :ranch_tcp, :undefined, %{env: %{dispatch: [{:_, [], [{:_, [], Phoenix.Endpoint.Cowboy2Handler, {AppWeb.Endpoint, []}}]}]}, stream_handlers: [Plug.Cowboy.Stream]}, "", %{}, {{127, 0, 0, 1}, 61063}, {{127, 0, 0, 1}, 4000}, :undefined, #Reference<0.3022468478.150208513.95764>, true, 2, {:ps_request_line, 0}, 65535, 1, :done, 1000, [{:stream, 1, {Plug.Cowboy.Stream, {:state, :undefined, AppWeb.Endpoint.HTTP, #PID<0.6371.0>, :undefined, :undefined, :undefined, :undefined, 0, :nofin, "", 0, :undefined, :normal}}, "GET", :"HTTP/1.1", :undefined, :undefined, 0, []}], [{:child, #PID<0.6371.0>, 1, 5000, :undefined}]}, 1, [{:response, "401 Unauthorized", %{"cache-control" => "max-age=0, private, must-revalidate", "content-length" => "0", "date" => "Sat, 29 Aug 2020 17:32:18 GMT", "server" => "Cowboy", "x-request-id" => "Fi_Nf1nWhRxOi1UAAQPB"}, ""}]], [file: '/Users/raph/Code/App/api/deps/cowboy/src/cowboy_http.erl', line: 954]}, {:cowboy_http, :loop, 1, [file: '/Users/raph/Code/App/api/deps/cowboy/src/cowboy_http.erl', line: 254]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}
注意:所有情况下响应发送成功,之后出现上述错误。
错误是什么意思,我该如何避免?
更新
我刚刚注意到上面的代码似乎试图发送两个响应:
[info] Sent 200 in 41ms
[info] Sent 401 in 41ms
鉴于我的真实代码更接近于:
def check(conn, _) do
if auth_token = get_session(conn, :auth_token) do
if user = Accounts.get_user_by_session_token(auth_token) do
send_resp(conn, 200, Map.get(user, :email))
end
end
send_resp(conn, 401, "")
end
编写上述逻辑的惯用方法是什么 send_resp
只被调用一次?
下面的实现没有错误,但感觉可以用更惯用的方式重构它。
def check(conn, _) do
if auth_token = get_session(conn, :auth_token) do
if user = Accounts.get_user_by_session_token(auth_token) do
send_resp(conn, 200, Map.get(user, :email))
else
send_resp(conn, 401, "")
end
else
send_resp(conn, 401, "")
end
end
假设有一个 User
结构,我认为这更符合习惯:
def check(conn, _) do
with token when is_binary(token) <- get_session(conn, :auth_token),
%User{} = user <- Accounts.get_user_by_session_token(token) do
send_resp(conn, 200, user.email)
else
_ -> send_resp(conn, 401, "")
end
end