Skip to content

Commit 17555fa

Browse files
Add a better error for undefined macros (#3343)
* Add a better error for undefined macros * Add check/error when installed packages < specified packages * fix integration tests * Fix issue with null packages * Don't call _get_project_directories() twice Co-authored-by: Jeremy Cohen <jtcohen6@gmail.com> * Fix some integration and unit tests * Make mypy happy Co-authored-by: Jeremy Cohen <jtcohen6@gmail.com> * Fix docs and rpc integration tests * Fix (almost) all the rpc tests Co-authored-by: Jeremy Cohen <jtcohen6@gmail.com>
1 parent 36e0ab9 commit 17555fa

File tree

9 files changed

+34
-27
lines changed

9 files changed

+34
-27
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Stop clobbering default keyword arguments for jinja test definitions ([#3329](https://github.com/fishtown-analytics/dbt/issues/3329), [#3340](https://github.com/fishtown-analytics/dbt/pull/3340))
99
- Fix unique_id generation for generic tests so tests with the same FQN but different configuration will run. ([#3254](https://github.com/fishtown-analytics/dbt/issues/3254), [#3335](https://github.com/fishtown-analytics/dbt/issues/3335))
1010
- Update the snowflake adapter to only comment on a column if it exists when using the persist_docs config ([#3039](https://github.com/fishtown-analytics/dbt/issues/3039), [#3149](https://github.com/fishtown-analytics/dbt/pull/3149))
11+
- Add a better error messages for undefined macros and when there are less packages installed than specified in `packages.yml`. ([#2999](https://github.com/fishtown-analytics/dbt/issues/2999))
1112
- Separate `compiled_path` from `build_path`, and print the former alongside node error messages ([#1985](https://github.com/fishtown-analytics/dbt/issues/1985), [#3327](https://github.com/fishtown-analytics/dbt/pull/3327))
1213
- Fix exception caused when running `dbt debug` with BigQuery connections ([#3314](https://github.com/fishtown-analytics/dbt/issues/3314), [#3351](https://github.com/fishtown-analytics/dbt/pull/3351))
1314

@@ -19,6 +20,7 @@ Contributors:
1920
- [@panasenco](https://github.com/panasenco) ([#3315](https://github.com/fishtown-analytics/dbt/pull/3315))
2021
- [@peiwangdb](https://github.com/peiwangdb) ([#3344](https://github.com/fishtown-analytics/dbt/pull/3344))
2122
- [@elikastelein](https://github.com/elikastelein) ([#3149](https://github.com/fishtown-analytics/dbt/pull/3149))
23+
- [@jaypeedevlin](https://github.com/jaypeedevlin) ([#2999](https://github.com/fishtown-analytics/dbt/issues/2999))
2224

2325
## dbt 0.20.0b1 (May 03, 2021)
2426

core/dbt/clients/jinja.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
from dbt.contracts.graph.parsed import ParsedSchemaTestNode
3030
from dbt.exceptions import (
3131
InternalException, raise_compiler_error, CompilationException,
32-
invalid_materialization_argument, MacroReturn, JinjaRenderingException
32+
invalid_materialization_argument, MacroReturn, JinjaRenderingException,
33+
UndefinedMacroException
3334
)
3435
from dbt import flags
3536
from dbt.logger import GLOBAL_LOGGER as logger # noqa
@@ -518,7 +519,7 @@ def catch_jinja(node=None) -> Iterator[None]:
518519
e.translated = False
519520
raise CompilationException(str(e), node) from e
520521
except jinja2.exceptions.UndefinedError as e:
521-
raise CompilationException(str(e), node) from e
522+
raise UndefinedMacroException(str(e), node) from e
522523
except CompilationException as exc:
523524
exc.add_node(node)
524525
raise

core/dbt/config/runtime.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,17 @@ def load_dependencies(self) -> Mapping[str, 'RuntimeConfig']:
328328
if self.dependencies is None:
329329
all_projects = {self.project_name: self}
330330
internal_packages = get_include_paths(self.credentials.type)
331+
# raise exception if fewer installed packages than in packages.yml
332+
count_packages_specified = len(self.packages.packages) # type: ignore
333+
count_packages_installed = len(tuple(self._get_project_directories()))
334+
if count_packages_specified > count_packages_installed:
335+
raise_compiler_error(
336+
f'dbt found {count_packages_specified} package(s) '
337+
f'specified in packages.yml, but only '
338+
f'{count_packages_installed} package(s) installed '
339+
f'in {self.modules_path}. Run "dbt deps" to '
340+
f'install package dependencies.'
341+
)
331342
project_paths = itertools.chain(
332343
internal_packages,
333344
self._get_project_directories()

core/dbt/exceptions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,15 @@ class JinjaRenderingException(CompilationException):
289289
pass
290290

291291

292+
class UndefinedMacroException(CompilationException):
293+
294+
def __str__(self, prefix='! ') -> str:
295+
msg = super().__str__(prefix)
296+
return f'{msg}. This can happen when calling a macro that does ' \
297+
'not exist. Check for typos and/or install package dependencies ' \
298+
'with "dbt deps".'
299+
300+
292301
class UnknownAsyncIDException(Exception):
293302
CODE = 10012
294303
MESSAGE = 'RPC server got an unknown async ID'

test/integration/029_docs_generate_tests/test_docs_generate.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,6 @@ def dir(path):
130130
def models(self):
131131
return self.dir("models")
132132

133-
@property
134-
def packages_config(self):
135-
return {
136-
'packages': [
137-
{
138-
'git': 'https://github.com/fishtown-analytics/dbt-integration-project',
139-
'revision': 'dbt/0.17.0',
140-
},
141-
],
142-
}
143-
144133
@property
145134
def project_config(self):
146135
return {

test/integration/033_event_tracking_test/test_events.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def run_event_test(
4646
expect_pass=True,
4747
expect_raise=False
4848
):
49+
self.run_dbt(["deps"])
4950
track_fn.reset_mock()
5051

5152
project_id = hashlib.md5(
@@ -541,6 +542,7 @@ def test__postgres_event_tracking_model_error(self):
541542
@use_profile("postgres")
542543
def test__postgres_event_tracking_tests(self):
543544
# TODO: dbt does not track events for tests, but it should!
545+
self.run_dbt(["deps"])
544546
self.run_dbt(["run", "--model", "example", "example_2"])
545547

546548
expected_calls = [

test/integration/059_source_overrides_test/test_source_overrides.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,6 @@ def _set_updated_at_to(self, delta):
7676

7777
@use_profile('postgres')
7878
def test_postgres_source_overrides(self):
79-
# without running 'deps', our source overrides are invalid
80-
_, stdout = self.run_dbt_and_capture(['compile'], strict=False)
81-
self.assertRegex(stdout, r'WARNING(\x1b\[0m\])?: During parsing, dbt encountered source overrides that had no target')
82-
schema_path = os.path.join('models', 'schema.yml')
83-
self.assertIn(f'Source localdep.my_source (in {schema_path})', stdout)
8479
self.run_dbt(['deps'])
8580
seed_results = self.run_dbt(['seed'])
8681
assert len(seed_results) == 5

test/integration/100_rpc_test/test_rpc.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,8 @@ def test_invalid_requests_postgres(self):
722722
task_tags={'some_tag': True, 'another_tag': 'blah blah blah'}
723723
).json()
724724
error_data = self.assertIsErrorWith(data, 10004, 'Compilation Error', {
725-
'type': 'CompilationException',
726-
'message': "Compilation Error in rpc mymodel (from remote system)\n 'reff' is undefined",
725+
'type': 'UndefinedMacroException',
726+
'message': "Compilation Error in rpc mymodel (from remote system)\n 'reff' is undefined. This can happen when calling a macro that does not exist. Check for typos and/or install package dependencies with \"dbt deps\".",
727727
'compiled_sql': None,
728728
'raw_sql': 'select * from {{ reff("nonsource_descendant") }}',
729729
'tags': {'some_tag': True, 'another_tag': 'blah blah blah'}
@@ -1143,11 +1143,8 @@ def models(self):
11431143
def _check_start_predeps(self):
11441144
self.assertFalse(os.path.exists('./dbt_modules'))
11451145
status = self.assertIsResult(self.query('status').json())
1146-
self.assertEqual(status['state'], 'ready')
1147-
1148-
self.assertIsError(self.async_query('compile').json())
1149-
if os.path.exists('./dbt_modules'):
1150-
self.assertEqual(len(os.listdir('./dbt_modules')), 0)
1146+
# will return an error because defined dependency is missing
1147+
self.assertEqual(status['state'], 'error')
11511148
return status
11521149

11531150
def _check_deps_ok(self, status):

test/rpc/test_deps.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ def deps_with_packages(packages, bad_packages, project_dir, profiles_dir, schema
1919
profiles_dir=profiles_dir,
2020
schema=schema,
2121
test_kwargs={},
22+
criteria='error',
2223
)
2324

2425
with querier_ctx as querier:
2526
# we should be able to run sql queries at startup
26-
querier.async_wait_for_result(querier.run_sql('select 1 as id'))
27+
querier.is_error(querier.run_sql('select 1 as id'))
2728

28-
# the status should be something positive
29+
# the status should be an error as deps wil not be defined
2930
querier.is_result(querier.status())
3031

3132
# deps should pass

0 commit comments

Comments
 (0)