Skip to content

Commit 731ca7a

Browse files
ChenyuLInxjtcohen6
authored andcommitted
fire proper event for inline query error (#7960)
1 parent a935df9 commit 731ca7a

File tree

9 files changed

+522
-451
lines changed

9 files changed

+522
-451
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Fixes
2+
body: Inline query emit proper error message
3+
time: 2023-06-28T14:41:25.699046-07:00
4+
custom:
5+
Author: ChenyuLInx
6+
Issue: "7940"

core/dbt/events/types.proto

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,16 @@ message UnsupportedConstraintMaterializationMsg {
12051205
UnsupportedConstraintMaterialization data = 2;
12061206
}
12071207

1208+
// I069
1209+
message ParseInlineNodeError{
1210+
NodeInfo node_info = 1;
1211+
string exc = 2;
1212+
}
1213+
message ParseInlineNodeErrorMsg {
1214+
EventInfo info = 1;
1215+
ParseInlineNodeError data = 2;
1216+
}
1217+
12081218
// M - Deps generation
12091219

12101220
// M001

core/dbt/events/types.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,14 @@ def message(self) -> str:
11691169
return line_wrap_message(warning_tag(msg))
11701170

11711171

1172+
class ParseInlineNodeError(ErrorLevel):
1173+
def code(self):
1174+
return "I069"
1175+
1176+
def message(self) -> str:
1177+
return "Error while parsing node: " + self.node_info.node_name + "\n" + self.exc
1178+
1179+
11721180
# =======================================================
11731181
# M - Deps generation
11741182
# =======================================================

core/dbt/events/types_pb2.py

Lines changed: 437 additions & 433 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/dbt/task/compile.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@
55
from dbt.contracts.results import RunStatus, RunResult
66
from dbt.events.base_types import EventLevel
77
from dbt.events.functions import fire_event
8-
from dbt.events.types import CompiledNode, Note
9-
from dbt.exceptions import DbtInternalError, DbtRuntimeError
8+
from dbt.events.types import CompiledNode, Note, ParseInlineNodeError
9+
from dbt.exceptions import (
10+
CompilationError,
11+
DbtInternalError,
12+
DbtRuntimeError,
13+
Exception as DbtException,
14+
)
15+
1016
from dbt.graph import ResourceTypeSelector
1117
from dbt.node_types import NodeType
1218
from dbt.parser.manifest import write_manifest, process_node
@@ -129,14 +135,26 @@ def defer_to_manifest(self, adapter, selected_uids: AbstractSet[str]):
129135

130136
def _runtime_initialize(self):
131137
if getattr(self.args, "inline", None):
132-
block_parser = SqlBlockParser(
133-
project=self.config, manifest=self.manifest, root_project=self.config
134-
)
135-
sql_node = block_parser.parse_remote(self.args.inline, "inline_query")
136-
process_node(self.config, self.manifest, sql_node)
137-
# keep track of the node added to the manifest
138-
self._inline_node_id = sql_node.unique_id
139-
138+
try:
139+
block_parser = SqlBlockParser(
140+
project=self.config, manifest=self.manifest, root_project=self.config
141+
)
142+
sql_node = block_parser.parse_remote(self.args.inline, "inline_query")
143+
process_node(self.config, self.manifest, sql_node)
144+
# keep track of the node added to the manifest
145+
self._inline_node_id = sql_node.unique_id
146+
except CompilationError as exc:
147+
fire_event(
148+
ParseInlineNodeError(
149+
exc=str(exc.msg),
150+
node_info={
151+
"node_path": "sql/inline_query",
152+
"node_name": "inline_query",
153+
"unique_id": "sqloperation.test.inline_query",
154+
},
155+
)
156+
)
157+
raise DbtException("Error parsing inline query")
140158
super()._runtime_initialize()
141159

142160
def after_run(self, adapter, results):

dev-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ types-pytz
3131
types-requests
3232
types-setuptools
3333
wheel
34+
mocker

tests/functional/compile/test_compile.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import json
2+
import pathlib
13
import pytest
24

35
from dbt.cli.main import dbtRunner
4-
from dbt.exceptions import DbtRuntimeError, TargetNotFoundError
6+
from dbt.exceptions import DbtRuntimeError, Exception as DbtException
57
from dbt.tests.util import run_dbt, run_dbt_and_capture
68
from tests.functional.compile.fixtures import (
79
first_model_sql,
@@ -137,9 +139,7 @@ def test_select_pass_empty(self, project):
137139
assert "Compiled node 'second_model' is:" in log_output
138140

139141
def test_inline_fail(self, project):
140-
with pytest.raises(
141-
TargetNotFoundError, match="depends on a node named 'third_model' which was not found"
142-
):
142+
with pytest.raises(DbtException, match="Error parsing inline query"):
143143
run_dbt(["compile", "--inline", "select * from {{ ref('third_model') }}"])
144144

145145
def test_multiline_jinja(self, project):
@@ -174,3 +174,28 @@ def test_compile_inline_not_add_node(self, project):
174174
populate_cache=False,
175175
)
176176
assert len(manifest.nodes) == 4
177+
178+
def test_compile_inline_syntax_error(self, project, mocker):
179+
patched_fire_event = mocker.patch("dbt.task.compile.fire_event")
180+
with pytest.raises(DbtException, match="Error parsing inline query"):
181+
run_dbt(["compile", "--inline", "select * from {{ ref(1) }}"])
182+
# Event for parsing error fired
183+
patched_fire_event.assert_called_once()
184+
185+
def test_compile_inline_ref_node_not_exist(self, project, mocker):
186+
patched_fire_event = mocker.patch("dbt.task.compile.fire_event")
187+
with pytest.raises(DbtException, match="Error parsing inline query"):
188+
run_dbt(["compile", "--inline", "select * from {{ ref('third_model') }}"])
189+
# Event for parsing error fired
190+
patched_fire_event.assert_called_once()
191+
192+
def test_graph_summary_output(self, project):
193+
"""Ensure that the compile command generates a file named graph_summary.json
194+
in the target directory, that the file contains valid json, and that the
195+
json has the high level structure it should."""
196+
dbtRunner().invoke(["compile"])
197+
summary_path = pathlib.Path(project.project_root, "target/graph_summary.json")
198+
with open(summary_path, "r") as summary_file:
199+
summary = json.load(summary_file)
200+
assert "_invocation_id" in summary
201+
assert "linked" in summary

tests/functional/show/test_show.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
22

3-
from dbt.exceptions import DbtRuntimeError
3+
from dbt.exceptions import DbtRuntimeError, Exception as DbtException
44
from dbt.tests.util import run_dbt_and_capture, run_dbt
55
from tests.functional.show.fixtures import (
66
models__second_ephemeral_model,
@@ -73,9 +73,7 @@ def test_inline_pass(self, project):
7373

7474
def test_inline_fail(self, project):
7575
run_dbt(["build"])
76-
with pytest.raises(
77-
DbtRuntimeError, match="depends on a node named 'third_model' which was not found"
78-
):
76+
with pytest.raises(DbtException, match="Error parsing inline query"):
7977
run_dbt(["show", "--inline", "select * from {{ ref('third_model') }}"])
8078

8179
def test_ephemeral_model(self, project):

tests/unit/test_events.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ def test_event_codes(self):
234234
ref_node_name="", ref_node_package="", ref_node_version="", ref_max_version=""
235235
),
236236
types.UnsupportedConstraintMaterialization(materialized=""),
237+
types.ParseInlineNodeError(exc=""),
237238
# M - Deps generation ======================
238239
types.GitSparseCheckoutSubdirectory(subdir=""),
239240
types.GitProgressCheckoutRevision(revision=""),

0 commit comments

Comments
 (0)