Mix.exs does not compile

Background

I have a mix.exs file that doesn’t compile. I have double checked the file but found nothing.

mix.exs

defmodule Bidtor.Mixfile do
  use Mix.Project

  def project do
    [
      app: :my_app,
      version: get_version_number(),
      elixir: "~> 1.8",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      build_embedded: Mix.env() == :prod,
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test]
    ]
  end

  def application do
    [
      mod: {MyApp, []},
      extra_applications: [:logger, :runtime_tools]
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
  defp elixirc_paths(_), do: ["lib", "web"]

  defp deps do
    [
      {:phoenix,        "~> 1.2"  },
      {:phoenix_html,   "~> 2.0"  },
      {:gettext,        "~> 0.9"  },
      {:harakiri,       "~> 1.1"  },
      {:jason,          "~> 1.0"  },
      {:geolix,         "0.10.0"  },
      {:cipher,         ">= 1.3.0"},
      {:observer_cli,   "~> 1.4"  },
      {:alfred,         git: "private_github_repo_link", tag: "1.4.1", override: true  },
      {:alfred_http,    git: "private_github_repo_link", tag: "1.0.0"  },
      {:alfred_payout,  git: "private_github_repo_link", tag: "0.1.1"  },
      {:bottler,        github: "rubencaro/bottler" },
      {:mix_test_watch, "~> 0.8",   only: [:dev, :test],  runtime: false  },
      {:credo,          "~> 1.0.0", only: [:dev, :test],  runtime: false  },
      {:excoveralls,    "~> 0.10",  only: [:dev, :test] }
    ]
  end

  # Get version number based on git commit
  #
  defp get_version_number do
    commit = :os.cmd('git rev-parse --short HEAD') |> to_string |> String.trim_trailing("\n")
    v = "0.1.0+#{commit}"

    case Mix.env() do
      :dev -> v <> "dev"
      _ -> v
    end
  end
end

Error

an exception was raised:
** (Mix.Config.LoadError) could not load config config/config.exs
** (ArgumentError) argument error
(stdlib) :erl_eval.expr/3
(elixir) src/elixir.erl:233: :elixir.eval_forms/4
(elixir) lib/code.ex:192: Code.eval_string/3
(mix) lib/mix/config.ex:188: Mix.Config.read!/2
(mix) lib/mix/tasks/loadconfig.ex:37: Mix.Tasks.Loadconfig.load/1
(mix) lib/mix/tasks/loadconfig.ex:27: Mix.Tasks.Loadconfig.run/1
(mix) lib/mix/task.ex:314: Mix.Task.run_task/3
(language_server) lib/language_server/build.ex:147: ElixirLS.LanguageServer.Build.reload_project/0(undefined)

I cannot even run mix deps.get:

** (ArgumentError) argument error
(stdlib) eval_bits.erl:101: :eval_bits.eval_exp_field1/6
(stdlib) eval_bits.erl:92: :eval_bits.eval_field/3
(stdlib) eval_bits.erl:68: :eval_bits.expr_grp/4
(stdlib) erl_eval.erl:484: :erl_eval.expr/5
(stdlib) erl_eval.erl:888: :erl_eval.expr_list/6
(stdlib) erl_eval.erl:240: :erl_eval.expr/5
(stdlib) erl_eval.erl:232: :erl_eval.expr/5

Question

What is wrong with this file?

I don‘t think there‘s anything wrong with your mixfile. Looking at the error message it seems like your config file doesn‘t exist, have you checked this?

It most definitely exists :S (we are talking about config/config.exs, right?

Yes, you likely have some error in the file or the files it loads. Can you include them as well?

After checking my config file, I realized the following line is causing the problem:

config :my_app,
  geolix_db_path: System.get_env("PROJECTS_PATH") <> "/my_app/lib/geoip/GeoLite2-Country.mmdb"

How can this cause such a cryptic error?

The stacktrace is obfuscated because the config file is being evaluated. The evaluator is just erlang code executing the erlang AST instead of the normal runtime interpreter. What you are seeing is the stacktrace from the evaluator instead of from your code.

I am not sure what can be done to improve this without changing the evaluator or how it works.

2 Likes

The problem (found out today) was that

System.get_env("PROJECTS_PATH") 

was returning nil. Now I am not sure how this could be improved, perhaps a pre check to see if all env vars are setup ? … Thanks for the help anyway!

Maybe we should have a System.fetch_env!/1 function that raises on missing variables?

2 Likes

Straight to the heart …

@ericmj
Apparently we won’t ever have System.fetch_env! because José Valim does not see use in one.

At least that’s what get, the reason being the interfaces are different and that he doesn’t like System.fetch_env in the first place, so adding yet another fetch function would be even worst.

I may be missing something, feel free to correct me.

https://github.com/elixir-lang/elixir/issues/5608

Since we have a concrete example of where a function like this would improve error messages it might be worth reopening the discussion. I would recommend creating a new thread on the elixir-lang-core mailing list referencing this thread.

1 Like

You mean, GitHub issues, right ?

Proposals should be sent to the mailing list: https://groups.google.com/forum/#!msg/elixir-lang-core.

3 Likes

PR done and accepted:

https://github.com/elixir-lang/elixir/pull/8846

We will now have System.fecth_env and System.fetch_env!

Thanks for the help!

3 Likes