Mix.env() in production no longer produces nil, but crashes Mix.State genserver

With Elixir 1.7.2/OTP21 Mix.env() no longer produces nil in production (i.e. inside release). Instead crashes because GenServer Mix.State isn’t running. I found a workaround in checking if Mix.State is running (Process.whereis(Mix.State) != nil) but surely Mix.env() should return nil, right?

    ** (EXIT) exited in: GenServer.call(Mix.State, {:get, {Map, :get, [:env, :dev]}}, 5000)
        ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
1 Like

:wave:

but surely Mix.env() should return nil , right?

I’d rather crash. Returning nil from a not-started application seems confusing to me.

In what situations do you use Mix.env() in production?

Well, I have a few if Mix.env() == :test do things scenarios which would be ignored if Mix.env() returned nil. Now I have to wrap them in a if Process.whereis(Mix.State) != nil.

Try replacing them with

if unquote(Mix.env() == :test) do
# ...

if these invocations are inside functions.

2 Likes

Unless you have mix in your :extra_applications list, it simply should fail, as Mix.env/0 isn’t available.

If though you have it in your :extra_applications, it should properly return :prod

So I’m not sure what your problem is.

3 Likes

Build or Runtime compare?

Yeah I’m pretty confused about how this wasn’t blowing up already, I normally get a Module Mix is unavailable error. The general solution here is to not call Mix.env in runtime code. You can either do so at build time OR you use if Application.get_env(:my_app, :something_meaningful) instead, and then set that flag in your config.exs

Runtime. But I probably just have to rethink my approach :slight_smile: Thanks

I was facing problems with the dyalizer and using the unquote() macro fixed the dialyzer warnings.