Conditional forward in Router based on run-time configuration

I need to use the forward macro in my application’s router only if a configuration flag is true, otherwise I don’t need to forward. I’ve set the config flag to my Endpoint and am trying to access it in the router module as such:

if MyApp.Endpoint.config(:use_sent_emails_plug, false) do
  forward "/sent-emails", Bamboo.SentEmailViewerPlug

However this approach throws a compilation error:

== Compilation error in file lib/my_app_web/router.ex ==
** (ArgumentError) argument error
    (stdlib) :ets.lookup(MyAppWeb.Endpoint, :use_sent_emails_plug)
    lib/phoenix/endpoint.ex:540: MyAppWeb.Endpoint.config/2
    lib/my_app_web/router.ex:4: (module)
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
    (elixir) lib/kernel/parallel_compiler.ex:229: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7

Thanks in advance for any help and insight.

@stefpankov The config function you’re calling is designed to allow for dynamic runtime configuration, and errors if you call it at compile time.

If you don’t need to change the value at runtime you should just access the config value directly:

if Application.get_env(:my_app, MyApp.Endpoint)[:use_sent_emails_plug] do
  # etc

I’d probably move it out from under Endpoint at that point as well since it isn’t really part of the official endpoint config.

I had the mail adapter be configurable at run-time in the releases.exs config file, however i couldn’t really find a way to use that configuration in the router. After a lot of digging I figured out the whole compile time vs. run-time configuration and realized that there’s really no need for me to configure the mail driver at run-time so now for production I configure the mail driver with an env variable and it can be either local or sendgrid for different target environments.

So now the check looks like this:

if Application.get_env(:my_app, MyApp.Mailer)[:adapter] == Bamboo.LocalAdapter do
  forward "/sent-emails", Bamboo.SentEmailViewerPlug
1 Like