Skip to content

Commit 1f9d9d7

Browse files
committed
feat: Error on undefined template variables
Previously, if a Jinja2 template contained a variable that was not defined, the template would fail to render silently, and the raw, un-rendered string would be returned as the value. This could lead to unexpected behavior and make debugging difficult. This change modifies the Jinja2 environment to use , which raises an when a template variable is not defined. This error is now caught and re-raised as a with a more informative message, making it clear which variable is causing the issue. A new test has been added to verify that an error is raised when a template contains an undefined variable.
1 parent 11e4f15 commit 1f9d9d7

2 files changed

Lines changed: 61 additions & 4 deletions

File tree

src/envars/main.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from collections import deque
44

55
import yaml
6-
from jinja2 import Environment, meta
6+
from jinja2 import Environment, StrictUndefined, meta
7+
from jinja2.exceptions import UndefinedError
78

89
from .aws_cloudformation import CloudFormationExports
910
from .aws_kms import AWSKMSAgent
@@ -377,7 +378,7 @@ def _get_resolved_variables(
377378

378379
# Template substitution with Jinja2
379380
sorted_order = _check_for_circular_dependencies(resolved_vars)
380-
jinja_env = Environment(autoescape=True)
381+
jinja_env = Environment(autoescape=True, undefined=StrictUndefined)
381382
rendered = {}
382383
for var_name in sorted_order:
383384
value = resolved_vars[var_name]
@@ -387,8 +388,8 @@ def _get_resolved_variables(
387388
context = {"env": os.environ}
388389
context.update(rendered)
389390
rendered[var_name] = template.render(context)
390-
except Exception:
391-
rendered[var_name] = value
391+
except UndefinedError as e:
392+
raise ValueError(f"Error rendering template for variable '{var_name}': {e}") from e
392393
else:
393394
rendered[var_name] = value
394395
resolved_vars = rendered

tests/test_main.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,59 @@ def test_resolve_cloudformation_export(tmp_path, monkeypatch):
333333
assert "MY_EXPORT" in resolved_vars
334334
assert resolved_vars["MY_EXPORT"] == "my-cf-export-value"
335335
mock_cf_exports.get_export_value.assert_called_once_with("my-cf-export")
336+
337+
338+
def test_resolve_jinja2_template(tmp_path, monkeypatch):
339+
"""Test that Jinja2 templates are resolved correctly."""
340+
yaml_content = """
341+
configuration:
342+
environments:
343+
- dev
344+
locations:
345+
- local: "local"
346+
347+
environment_variables:
348+
GREETING:
349+
default: "Hello"
350+
NAME:
351+
default: "World"
352+
MESSAGE:
353+
default: "{{ GREETING }}, {{ NAME }}!"
354+
SHELL_VAR:
355+
default: "Value is: {{ env.get('MY_SHELL_VAR', 'default') }}"
356+
"""
357+
file_path = create_yaml_file(tmp_path, yaml_content)
358+
manager = load_from_yaml(file_path)
359+
360+
# Test with shell variable set
361+
monkeypatch.setenv("MY_SHELL_VAR", "from_shell")
362+
resolved_vars = _get_resolved_variables(manager, loc="local", env="dev", decrypt=True)
363+
assert resolved_vars["MESSAGE"] == "Hello, World!"
364+
assert resolved_vars["SHELL_VAR"] == "Value is: from_shell"
365+
366+
# Test with shell variable not set (should use default)
367+
monkeypatch.delenv("MY_SHELL_VAR", raising=False)
368+
resolved_vars = _get_resolved_variables(manager, loc="local", env="dev", decrypt=True)
369+
assert resolved_vars["SHELL_VAR"] == "Value is: default"
370+
371+
372+
def test_resolve_template_with_undefined_variable_raises_error(tmp_path):
373+
"""Test that a template with an undefined variable raises a ValueError."""
374+
yaml_content = """
375+
configuration:
376+
environments:
377+
- dev
378+
locations:
379+
- local: "local"
380+
381+
environment_variables:
382+
MESSAGE:
383+
default: "Hello, {{ UNDEFINED_VAR }}"
384+
"""
385+
file_path = create_yaml_file(tmp_path, yaml_content)
386+
manager = load_from_yaml(file_path)
387+
388+
with pytest.raises(
389+
ValueError, match="Error rendering template for variable 'MESSAGE': 'UNDEFINED_VAR' is undefined"
390+
):
391+
_get_resolved_variables(manager, loc="local", env="dev", decrypt=True)

0 commit comments

Comments
 (0)