Skip to content

Commit 637b80f

Browse files
Chore: Provide additional info in jinja rendering errors
1 parent cd37002 commit 637b80f

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

sqlmesh/core/renderer.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
from contextlib import contextmanager
66
from functools import partial
77
from pathlib import Path
8+
import re
9+
from sys import exc_info
10+
from traceback import walk_tb
11+
from jinja2 import UndefinedError
12+
from jinja2.runtime import Macro
813

914
from sqlglot import exp, parse
1015
from sqlglot.errors import SqlglotError
@@ -247,9 +252,45 @@ def _resolve_table(table: str | exp.Table) -> str:
247252
except ParsetimeAdapterCallError:
248253
raise
249254
except Exception as ex:
250-
raise ConfigError(
251-
f"Could not render or parse jinja at '{self._path}'.\n{ex}"
252-
) from ex
255+
error_details: t.List[str] = []
256+
if isinstance(ex, UndefinedError):
257+
try:
258+
_, _, exc_traceback = exc_info()
259+
for frame, _ in walk_tb(exc_traceback):
260+
if frame.f_code.co_name == "_invoke":
261+
macro = frame.f_locals.get("self")
262+
if isinstance(macro, Macro):
263+
arguments = frame.f_locals.get("arguments", [])
264+
arg_strs = [
265+
f"'{a}'" if isinstance(a, str) else str(a)
266+
for a in arguments
267+
]
268+
error_details.append(
269+
f"\nError when calling jinja macro: {macro.name}({', '.join(arg_strs)})\n"
270+
)
271+
for package in self._jinja_macro_registry.packages:
272+
try:
273+
if macro_info := self._jinja_macro_registry._get_macro(
274+
macro.name, package
275+
):
276+
error_details.append(
277+
"Macro definition:\n" + macro_info.definition
278+
)
279+
break
280+
except:
281+
pass
282+
break
283+
except:
284+
# fall back to the generic error message if frame analysis fails
285+
pass
286+
287+
if match := re.search(r"'(\w+)'", str(ex)):
288+
error_details.append(f"\nUndefined macro/variable: '{match.group(1)}'\n")
289+
290+
error_msg = f"Could not render or parse jinja at '{self._path}'."
291+
error_msg += "\n" + "\n".join(error_details) if error_details else f"\n{ex}"
292+
293+
raise ConfigError(error_msg) from ex
253294

254295
if this_model:
255296
render_kwargs["this_model"] = this_model

0 commit comments

Comments
 (0)