Clojure: making missing environment variables fail at compile time
Have you ever deployed something to production only to have it break because of a missing environment variable? You can eliminate this risk with a simple macro.
First we write a regular function that throws an exception if System/getenv
can't find an environment variable. This gives us a runtime check.
(defn env-dynamic
[k]
(if-let [v (-> k name System/getenv)]
v
(throw (ex-info (str "Missing env variable: " k)
{:missing-env-variable k}))))
We then wrap it in a macro.
(defmacro env
[k]
(env-dynamic k))
This turns it into a compile time check.
(env :DATABASE_URL)
=>
Missing env variable: :DATABASE_URL
For this to work you will need to have access to environment variables at compile time. In practice this require your build pipeline to have access to the same environment variables as production.
The env-dynamic
function is useful for environment variables that differ between processes for example PORT
environment variable on a heroku dyno.
This macro guarantees your build will fail at compile time so production won't break because of a missing environment variable.