Skip to content

Commit

Permalink
fire proper event for inline query error (#7960)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChenyuLInx authored Jun 30, 2023
1 parent 8ee0fe0 commit 4c44c29
Show file tree
Hide file tree
Showing 9 changed files with 4,391 additions and 881 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20230628-144125.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: Inline query emit proper error message
time: 2023-06-28T14:41:25.699046-07:00
custom:
Author: ChenyuLInx
Issue: "7940"
9 changes: 9 additions & 0 deletions core/dbt/events/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,15 @@ message UnsupportedConstraintMaterializationMsg {
UnsupportedConstraintMaterialization data = 2;
}

// I069
message ParseInlineNodeError{
NodeInfo node_info = 1;
string exc = 2;
}
message ParseInlineNodeErrorMsg {
EventInfo info = 1;
ParseInlineNodeError data = 2;
}

// M - Deps generation

Expand Down
8 changes: 8 additions & 0 deletions core/dbt/events/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,14 @@ def message(self) -> str:
return line_wrap_message(warning_tag(msg))


class ParseInlineNodeError(ErrorLevel):
def code(self):
return "I069"

def message(self) -> str:
return "Error while parsing node: " + self.node_info.node_name + "\n" + self.exc


# =======================================================
# M - Deps generation
# =======================================================
Expand Down
5,184 changes: 4,321 additions & 863 deletions core/dbt/events/types_pb2.py

Large diffs are not rendered by default.

37 changes: 27 additions & 10 deletions core/dbt/task/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
from dbt.contracts.results import RunStatus, RunResult
from dbt.events.base_types import EventLevel
from dbt.events.functions import fire_event
from dbt.events.types import CompiledNode, Note
from dbt.exceptions import DbtInternalError
from dbt.events.types import CompiledNode, Note, ParseInlineNodeError
from dbt.exceptions import (
CompilationError,
DbtInternalError,
Exception as DbtException,
)

from dbt.graph import ResourceTypeSelector
from dbt.node_types import NodeType
from dbt.parser.manifest import write_manifest, process_node
Expand Down Expand Up @@ -118,14 +123,26 @@ def defer_to_manifest(self, adapter, selected_uids: AbstractSet[str]):

def _runtime_initialize(self):
if getattr(self.args, "inline", None):
block_parser = SqlBlockParser(
project=self.config, manifest=self.manifest, root_project=self.config
)
sql_node = block_parser.parse_remote(self.args.inline, "inline_query")
process_node(self.config, self.manifest, sql_node)
# keep track of the node added to the manifest
self._inline_node_id = sql_node.unique_id

try:
block_parser = SqlBlockParser(
project=self.config, manifest=self.manifest, root_project=self.config
)
sql_node = block_parser.parse_remote(self.args.inline, "inline_query")
process_node(self.config, self.manifest, sql_node)
# keep track of the node added to the manifest
self._inline_node_id = sql_node.unique_id
except CompilationError as exc:
fire_event(
ParseInlineNodeError(
exc=str(exc.msg),
node_info={
"node_path": "sql/inline_query",
"node_name": "inline_query",
"unique_id": "sqloperation.test.inline_query",
},
)
)
raise DbtException("Error parsing inline query")
super()._runtime_initialize()

def after_run(self, adapter, results):
Expand Down
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ types-pytz
types-requests
types-setuptools
wheel
mocker
20 changes: 16 additions & 4 deletions tests/functional/compile/test_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import re

from dbt.cli.main import dbtRunner
from dbt.exceptions import DbtRuntimeError, TargetNotFoundError
from dbt.exceptions import DbtRuntimeError, Exception as DbtException
from dbt.tests.util import run_dbt, run_dbt_and_capture, read_file
from tests.functional.compile.fixtures import (
first_model_sql,
Expand Down Expand Up @@ -161,9 +161,7 @@ def test_select_pass_empty(self, project):
assert "Compiled node 'second_model' is:" in log_output

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

def test_multiline_jinja(self, project):
Expand Down Expand Up @@ -199,6 +197,20 @@ def test_compile_inline_not_add_node(self, project):
)
assert len(manifest.nodes) == 4

def test_compile_inline_syntax_error(self, project, mocker):
patched_fire_event = mocker.patch("dbt.task.compile.fire_event")
with pytest.raises(DbtException, match="Error parsing inline query"):
run_dbt(["compile", "--inline", "select * from {{ ref(1) }}"])
# Event for parsing error fired
patched_fire_event.assert_called_once()

def test_compile_inline_ref_node_not_exist(self, project, mocker):
patched_fire_event = mocker.patch("dbt.task.compile.fire_event")
with pytest.raises(DbtException, match="Error parsing inline query"):
run_dbt(["compile", "--inline", "select * from {{ ref('third_model') }}"])
# Event for parsing error fired
patched_fire_event.assert_called_once()

def test_graph_summary_output(self, project):
"""Ensure that the compile command generates a file named graph_summary.json
in the target directory, that the file contains valid json, and that the
Expand Down
6 changes: 2 additions & 4 deletions tests/functional/show/test_show.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from dbt.exceptions import DbtRuntimeError
from dbt.exceptions import DbtRuntimeError, Exception as DbtException
from dbt.tests.util import run_dbt_and_capture, run_dbt
from tests.functional.show.fixtures import (
models__second_ephemeral_model,
Expand Down Expand Up @@ -73,9 +73,7 @@ def test_inline_pass(self, project):

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

def test_ephemeral_model(self, project):
Expand Down
1 change: 1 addition & 0 deletions tests/unit/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ def test_event_codes(self):
ref_model_latest_version="",
),
types.UnsupportedConstraintMaterialization(materialized=""),
types.ParseInlineNodeError(exc=""),
# M - Deps generation ======================
types.GitSparseCheckoutSubdirectory(subdir=""),
types.GitProgressCheckoutRevision(revision=""),
Expand Down

0 comments on commit 4c44c29

Please sign in to comment.