Add a distinct exception for missing environment variables
#480 opened on 2026年7月10日
Repository metrics
- Stars
- (1,366 stars)
- PR merge metrics
- (PR metrics pending)
説明
Description
EnvError currently represents both a missing required environment variable and the base class for validation failures:
class EnvError(ValueError):
...
class EnvValidationError(EnvError):
...
This makes it impossible to catch only the “variable is not set” case without also suppressing malformed values.
For example:
from environs import EnvError, env
try:
database = env.dj_db_url("DATABASE_URL")
except EnvError:
database = None
This handles an absent DATABASE_URL, but also silently catches an invalid value such as:
DATABASE_URL=not-a-database-url
env.dj_db_url() raises EnvValidationError, which is also an EnvError. Applications wanting optional configuration can therefore discard useful validation errors and fail later with less informative errors.
Proposed solution
Introduce a specific exception for missing variables, for example:
class EnvError(ValueError):
pass
class EnvNotSetError(EnvError):
pass
class EnvValidationError(EnvError):
pass
Then raise EnvNotSetError when a required variable is absent:
try:
database = env.dj_db_url("DATABASE_URL")
except EnvNotSetError:
database = None
This should be backward-compatible for callers already catching EnvError, while allowing callers to distinguish missing configuration from invalid configuration.
Reproduction
import os
from environs import EnvError, env
os.environ.pop("DATABASE_URL", None)
try:
env.dj_db_url("DATABASE_URL")
except Exception as error:
print(type(error).__name__)
# prints EnvError
os.environ["DATABASE_URL"] = "not-a-database-url"
try:
env.dj_db_url("DATABASE_URL")
except Exception as error:
print(type(error).__name__) # prints EnvValidationError
print(isinstance(error, EnvError)) # prints True
Observed with environs==15.0.1.