Repository: conan-io/conan
Pull request #17940 (2025-03-11 19:11:10)

improve jinja2 failure error messages
Changelog: Fix: Improve error message when ``jinja2`` profile rendering fails due to unexpected syntax.
Docs: Omit

Close https://github.com/conan-io/conan/issues/17932

czoido: changed to point to the release/2.14 branch
memsharded: > changed to point to the release/2.14 branch

Thanks!

Patch:
diff --git a/conan/internal/api/profile/profile_loader.py b/conan/internal/api/profile/profile_loader.py
index 5ed77b1f1..ddc19bb64 100644
--- a/conan/internal/api/profile/profile_loader.py
+++ b/conan/internal/api/profile/profile_loader.py
@@ -126,9 +126,9 @@ class ProfileLoader:
         # Always include the root Conan home "profiles" folder as secondary route for loading
         # imports and includes from jinja2 templates.
         loader_paths = [base_path, profiles_folder]
-        rtemplate = Environment(loader=FileSystemLoader(loader_paths)).from_string(text)
 
         try:
+            rtemplate = Environment(loader=FileSystemLoader(loader_paths)).from_string(text)
             text = rtemplate.render(context)
         except Exception as e:
             raise ConanException(f"Error while rendering the profile template file '{profile_path}'. "


Test patch:
diff --git a/test/integration/configuration/test_profile_jinja.py b/test/integration/configuration/test_profile_jinja.py
index dc3d3daf3..d8af563a1 100644
--- a/test/integration/configuration/test_profile_jinja.py
+++ b/test/integration/configuration/test_profile_jinja.py
@@ -266,9 +266,39 @@ class TestProfileDetectAPI:
 
 def test_profile_jinja_error():
     c = TestClient(light=True)
-    c.save({"profile1": "{% set kk = other() %}"})
+    profile = textwrap.dedent("""
+        {% set arr = [
+            {# comment that triggers the error #}
+            'smth'
+        ] %}""")
+    c.save({"profile1": profile,
+            "profile2": "include(profile1)",
+            "profile3": "include(profile2)",
+            "conanfile.txt": ""})
     c.run("profile show -pr=profile1", assert_error=True)
     assert "ERROR: Error while rendering the profile template file" in c.out
+    c.run("profile show -pr=profile2", assert_error=True)
+    assert "ERROR: Error reading 'profile2' profile: Error while " \
+           "rendering the profile template file " in c.out
+    assert "unexpected char '#' at 21" in c.out
+    c.run("profile show -pr=profile3", assert_error=True)
+    assert "ERROR: Error reading 'profile3' profile: Error reading 'profile2' profile: Error while " \
+           "rendering the profile template file " in c.out
+    assert "unexpected char '#' at 21" in c.out
+
+    # Also install messages
+    c.run("install . -pr=profile1", assert_error=True)
+    assert "ERROR: Error while rendering the profile template file" in c.out
+    assert "unexpected char '#' at 21" in c.out
+
+    c.run("install . -pr=profile2", assert_error=True)
+    assert "ERROR: Error reading 'profile2' profile: Error while " \
+           "rendering the profile template file " in c.out
+    assert "unexpected char '#' at 21" in c.out
+    c.run("install . -pr=profile3", assert_error=True)
+    assert "ERROR: Error reading 'profile3' profile: Error reading 'profile2' profile: Error while " \
+           "rendering the profile template file " in c.out
+    assert "unexpected char '#' at 21" in c.out
 
 
 def test_profile_macro_per_package():