sloria/environs

Add a distinct exception for missing environment variables

Open

#480 opened on 2026年7月10日

GitHub で見る
 (1 comment) (0 reactions) (0 assignees)Python (107 forks)github user discovery
enhancementhelp wanted

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.

コントリビューターガイド