We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Keeping compile_env values out of runtime.exs
almirsarajcic
Application.compile_env/3 bakes a value into the module when it compiles. If config/runtime.exs sets the same key, the two can disagree without anyone noticing:
# config/config.exs
config :my_app, :page_size, 20
# config/runtime.exs
config :my_app, :page_size, String.to_integer(System.get_env("PAGE_SIZE", "20"))
# lib/my_app/listing.ex
defmodule MyApp.Listing do
@page_size Application.compile_env(:my_app, :page_size)
def page_size, do: @page_size
end
Under Mix, PAGE_SIZE=50 changes the application environment but not the module:
{MyApp.Listing.page_size(), Application.get_env(:my_app, :page_size)}
#=> {20, 50}
mix run didn’t complain about it. A release built from the same code refuses to boot instead:
ERROR! the application :my_app has a different value set for key :page_size during runtime compared to compile time.
So it quietly runs with the wrong number locally and fails on deploy. Values that runtime.exs owns should be read at runtime:
def page_size, do: Application.fetch_env!(:my_app, :page_size)
Keep compile_env for values the compiler actually needs, like a router conditional, and set those only in the compile-time config files.
copied to clipboard