I just encountered an interesting error. I have a Phoenix controller with the following guard statement:
@valid_types ["servicer", "bank", "credit-card"]
def index(conn, %{"type" => type}) when type in @valid_types do
conn
|> put_status(200)
|> render("index.json", data: Institution.get_onboarding_list(type))
end
def index(conn, %{"type" => type}) when type not in @valid_types do
conn
|> put_status(400)
|> render(ErrorView, "query_params.json")
end
This controller function compiles on my machine locally with no problems. When I run the server locally and call the route the guard behaves correctly. I have tests which pass too.
However, when I deploy I get the following SyntaxError related to the not in in the guard statement in the second function clause.
[2017-10-02 23:47:52.291] [stdout]== Compilation error on file web/controllers/institution_controller.ex ==
[2017-10-02 23:47:52.306] [stdout]** (SyntaxError) web/controllers/institution_controller.ex:15: syntax error before: in
[2017-10-02 23:47:52.306] [stdout] (elixir) lib/kernel/parallel_compiler.ex:117: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1
def index(conn, %{"type" => type}) when type not in @valid_types do
I believe the correct syntax is when not type in instead of when type not in.
On a side note, the second function is logically implied, so you don’t need a guard clause there. For example, this will match anything that wasn’t picked up by your first function head:
def index(conn, _params) do
conn
|> put_status(400)
|> render(ErrorView, "query_params.json")
end
Huh, I wonder why the compiler didn’t catch that on my local machine.
I actually have one more case I didn’t mention, index(conn, _params) I’m using to get the institutions for a logged-in user who’s JWT is in the conn. That’s why I went to the trouble of writing those two function clauses.