Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions airflow/upgrade/rules/undefined_jinja_varaibles.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,24 @@ def _nested_check_rendered(self, rendered_content, seen_oids):
def _render_task_content(self, task, content, context):
completed_rendering = False
errors_while_rendering = []
renderend_content = ""
while not completed_rendering:
# Catch errors such as {{ object.element }} where
# object is not defined
try:
renderend_content = task.render_template(content, context)
completed_rendering = True
except Exception as e:
undefined_variable = re.sub(" is undefined", "", str(e))
undefined_variable = re.sub("'", "", undefined_variable)
context[undefined_variable] = dict()
except (ValueError, jinja2.UndefinedError) as value_error:
undefined_variable = re.search(r"'(.*?)'", str(value_error))[1]
message = "Could not find the object '{}'".format(undefined_variable)
errors_while_rendering.append(message)
context[undefined_variable] = dict()
if re.search(r".*has no attribute.*", str(value_error)):
break
except Exception as e:
errors_while_rendering.append(str(e))
break

return renderend_content, errors_while_rendering

def iterate_over_template_fields(self, task):
Expand Down
32 changes: 32 additions & 0 deletions tests/upgrade/rules/test_undefined_jinja_varaibles.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,31 @@ def setUpInvalidDag(self):
dag=self.invalid_dag,
)

miscellaneous_exception_command = """
{% for i in None %}
{% endfor %}
"""

BashOperator(
task_id="miscellaneous_exception",
depends_on_past=False,
bash_command=miscellaneous_exception_command,
dag=self.invalid_dag,
)

missing_attribute_command = """
echo "{{ params.undefined_variable.foo }}"
"""

BashOperator(
task_id="missing_attribute",
depends_on_past=False,
bash_command=missing_attribute_command,
dag=self.invalid_dag,
)



def setUp(self):
self.setUpValidDag()
self.setUpDagToSkip()
Expand Down Expand Up @@ -190,9 +215,16 @@ def test_invalid_check(self):
"dict object['undefined'] NestedTemplateField=att1 NestedTemplateField=nested1",
"Possible UndefinedJinjaVariable -> DAG: test-undefined-jinja-variables, "
"Task: templated_string, Attribute: env, Error: no such element: dict object['element']",
"Possible UndefinedJinjaVariable -> DAG: test-undefined-jinja-variables, "
"Task: miscellaneous_exception, Attribute: bash_command, "
"Error: 'NoneType' object is not iterable",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Error: 'NoneType' object is not iterable",
"Error: 'NoneType' object is not iterable, "

"Possible UndefinedJinjaVariable -> DAG: test-undefined-jinja-variables, "
"Task: missing_attribute, Attribute: bash_command, "
"Error: Could not find the object 'dict object'"
]

assert len(messages) == len(expected_messages)
assert [m for m in messages if m in expected_messages], len(messages) == len(
expected_messages
)