diff --git a/README.md b/README.md index d621a980..d01bec6c 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,21 @@ SECRET_KEY=YOURSECRETKEYGOESHERE # comment SECRET_HASH="something-with-a-#-hash" ``` +### Required Keys + +If a particular configuration value is required but not set, it's appropriate to raise an error. + +To require configuration keys: + +```ruby +# config/initializers/dotenv.rb + +Dotenv.require_keys("SERVICE_APP_ID", "SERVICE_KEY", "SERVICE_SECRET") +``` + +If any of the configuration keys above are not set, your application will raise an error during initialization. This method is preferred because it prevents runtime errors in a production application due to improper configuration. + + ## Frequently Answered Questions ### Can I use dotenv in production? diff --git a/lib/dotenv.rb b/lib/dotenv.rb index abf1441b..e2a1f2c1 100644 --- a/lib/dotenv.rb +++ b/lib/dotenv.rb @@ -1,5 +1,6 @@ require "dotenv/parser" require "dotenv/environment" +require "dotenv/missing_keys" # The top level Dotenv module. The entrypoint for the application logic. module Dotenv @@ -55,6 +56,12 @@ def instrument(name, payload = {}, &block) end end + def require_keys(*keys) + missing_keys = keys.flatten - ::ENV.keys + return if missing_keys.empty? + raise MissingKeys, missing_keys + end + def ignoring_nonexistent_files yield rescue Errno::ENOENT diff --git a/lib/dotenv/missing_keys.rb b/lib/dotenv/missing_keys.rb new file mode 100644 index 00000000..9439b641 --- /dev/null +++ b/lib/dotenv/missing_keys.rb @@ -0,0 +1,10 @@ +module Dotenv + class Error < StandardError; end + + class MissingKeys < Error # :nodoc: + def initialize(keys) + key_word = "key#{keys.size > 1 ? 's' : ''}" + super("Missing required configuration #{key_word}: #{keys.inspect}") + end + end +end diff --git a/spec/dotenv_spec.rb b/spec/dotenv_spec.rb index 4940a2fd..b95fc2d5 100644 --- a/spec/dotenv_spec.rb +++ b/spec/dotenv_spec.rb @@ -153,6 +153,20 @@ end end + describe "require keys" do + let(:env_files) { [".env", fixture_path("bom.env")] } + + before { Dotenv.load(*env_files) } + + it "raises exception with not defined mandatory ENV keys" do + expect { Dotenv.require_keys("BOM", "TEST") }.to \ + raise_error( + Dotenv::MissingKeys, + 'Missing required configuration key: ["TEST"]' + ) + end + end + describe "Unicode" do subject { fixture_path("bom.env") }