Mpanarin

Mpanarin

Hello everyone.

I am experiencing an issue, which I am pretty sure is caused just by me not understanding stuff. Which is usual :slight_smile:

I am currently writing a small package. Its only purpose is providing a few helper mix tasks. I want them to be configurable by the user through his Config but provide some defaults as well.
The issue is that even though I specified :env: key in the &application/0 in mix.exs the defaults are still missing and all of my Application.compile_env calls are failing obviously.

I traced the issue to my application not getting loaded. But why? I don’t understand why the hell application that I am trying to compile is not getting loaded?

Elixir version is 1.10.3 compiled with erlang 23.
important contents of the mix.exs:

defmodule FooBar.MixProject do
  use Mix.Project
  def project do
    [
      app: :foobar,
      version: "0.1.0",
      elixir: "~> 1.10"
    ]
  end

  def application do
    [
      extra_applications: [:logger],
      env: [
        foo: "bar"
      ]
    ]
  end
end

somewhere in the project:

defmodule FooBar.Spam do
  @foo Application.compile_env!(:foobar, :foo)
end

and when I run mix compile I get an error:

** (ArgumentError) could not fetch application environment :foo for application :foobar because the application was not loaded/started. If your application depends on :foobar at runtime, make sure to load/start it or list it under :extra_applications in your mix.exs file

So, the issue is pretty clear - application is not loaded. And if I load it manually when standing on pry it works.
My question is why it is not loaded by default? If I should load it myself, where is the best place to do so?

Showing Posts 1 to 9

Matsa59

Matsa59

I think Application — Elixir v1.20.2 could help you. I don’t spent many times on application but I think you miss mod

def application do
  [
    mod: {MyApp, []},
    extra_applications: [:logger],
    env: [
      foo: "bar"
    ]]
end

If someone could confirm (I don’t have my computer :/)

Edit : after re-reading I feel like I’m wrong and don’t reply to your problem

Mpanarin

Mpanarin OP

Yes, as far as i understand :mod key is for custom startup process. Like starting a supervision tree, etc.
But, tbh, my app is more of a library and not an OTP app per se and i don’t really need custom start logic…

In the same docs it is written

Generally, build tools like Mix take care of starting an application and all of its dependencies for you

So I expect it to load the application as well :\

Matsa59

Matsa59

Gonna check this morning, is it an open source project?

Matsa59

Matsa59

Sounds like it doesn’t read value from the function application in mix.exs. If you write it in any config file it works …

Can’t find any mention of that behavior anywhere …

Edit: add code bellow

defmodule FooBar.Spam do
  @foo Application.fetch_env(:foobar, :foo)
end

Return :error, it seems the env var define in application/0 is available only in runtime.

Mpanarin

Mpanarin OP

Thanks for the answers. But I still don’t understand.
It seems like compile_env! just doesn’t work at all…

Using fetch_env doesn’t help at all as it will just return :error. It will compile, yes, but the app still won’t be loaded and therefore values will still be empty. I just don’t understand why mix doesn’t load the application.
Shouldn’t it load the app on compile? Or when the task is run?
It looks like mix simply ignores it at all!

I think I will open an issue in elixir repo as I am starting to get really frustrated and the docs are not helpful here at all :\

Matsa59

Matsa59

In fact it’s a « normal » behavior. You asked for a compiled env. but application/0 sounds like to be available only in runtime.

So it doesn’t compile because you want a compiled env var that is not available.

However I don’t know if it’s a normal that the ˋapplication/0` is not available in compile time.

Share the issue please, I would like to follow that :wink:

For the moment add your env in config file it should work.

hauleth

hauleth

Using application/0 :env for compile-time-only environment values seems at least strange. Why use :env instead of the config/config.exs though?

And to answer your question more directly, as you see in documentation .app file is compiled after all Elixir files (as compile.app needs list of all modules in application), so it cannot be available during compilation. If you want to have compile-time environment then use config/config.exs.

Mpanarin

Mpanarin OP

Okay, that makes sense now, thanks for the answer! Then, I am fixing my issue in the wrong way.

I am writing a library and publishing it to hex. I want to make this library configurable I use compile env values throughout. But, as config.exs of my library won’t get published to hex as well as not available to the user of the library, I want to provide some defaults. As far as I understood I have only 2 options at this:

  1. Use compile_env/3 and provide defaults there. But that seems like a bad idea, as all of my defaults will be scattered.
  2. Use the :env key in application. Which works a bit differently than I expected and not an option for me.

Am I missing something? Is this truly the only available options?

hairyhum

hairyhum

Hi,

This is somewhat a workaround, but it seems to be working for me.
I have my default configuration in the config/config.exs and adding following to the mix.exs:

def application do
  [
    ...
    env: Application.get_all_env(:my_app)
  ]
end

After I run mix compile there is my config in the ebin/my_app.app file

Because config/config.exs is loaded before the compilation, mix compile.app has access to the application config.

I’m not sure if that idiomatic, but it works.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews