Skip to content

Commit 3f56cbc

Browse files
authored
Behavior flag to handle all warnings with warn_error logic (#11483)
1 parent 7cca847 commit 3f56cbc

File tree

4 files changed

+80
-1
lines changed

4 files changed

+80
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Features
2+
body: Add behavior flag for handling all warnings via warn_error logic
3+
time: 2025-04-10T11:10:23.344469-05:00
4+
custom:
5+
Author: QMalcolm
6+
Issue: "11116"

core/dbt/cli/requires.py

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from dbt_common.clients.system import get_env
4242
from dbt_common.context import get_invocation_context, set_invocation_context
4343
from dbt_common.events.base_types import EventLevel
44+
from dbt_common.events.event_manager_client import get_event_manager
4445
from dbt_common.events.functions import LOG_VERSION, fire_event
4546
from dbt_common.events.helpers import get_json_string_utcnow
4647
from dbt_common.exceptions import DbtBaseException as DbtException
@@ -74,6 +75,9 @@ def wrapper(*args, **kwargs):
7475
flags = Flags(ctx)
7576
ctx.obj["flags"] = flags
7677
set_flags(flags)
78+
get_event_manager().require_warn_or_error_handling = (
79+
flags.require_all_warnings_handled_by_warn_error
80+
)
7781

7882
# Reset invocation_id for each 'invocation' of a dbt command (can happen multiple times in a single process)
7983
reset_invocation_id()

core/dbt/contracts/project.py

+2
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ class ProjectFlags(ExtensibleDbtClassMixin):
348348
require_yaml_configuration_for_mf_time_spines: bool = False
349349
require_nested_cumulative_type_params: bool = False
350350
validate_macro_args: bool = False
351+
require_all_warnings_handled_by_warn_error: bool = False
351352

352353
@property
353354
def project_only_flags(self) -> Dict[str, Any]:
@@ -362,6 +363,7 @@ def project_only_flags(self) -> Dict[str, Any]:
362363
"require_yaml_configuration_for_mf_time_spines": self.require_yaml_configuration_for_mf_time_spines,
363364
"require_nested_cumulative_type_params": self.require_nested_cumulative_type_params,
364365
"validate_macro_args": self.validate_macro_args,
366+
"require_all_warnings_handled_by_warn_error": self.require_all_warnings_handled_by_warn_error,
365367
}
366368

367369

tests/functional/configs/test_warn_error_options.py

+68-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import pytest
44

55
from dbt.cli.main import dbtRunner, dbtRunnerResult
6-
from dbt.events.types import DeprecatedModel
6+
from dbt.events.types import (
7+
DeprecatedModel,
8+
MainEncounteredError,
9+
MicrobatchModelNoEventTimeInputs,
10+
)
711
from dbt.flags import get_flags
812
from dbt.tests.util import run_dbt, update_config_file
913
from dbt_common.events.base_types import EventLevel
@@ -229,3 +233,66 @@ def test_project_flags(self, project):
229233
# Note: WarnErrorOptions is not a dataclass, so you won't get "silence"
230234
# from to_dict or stringifying.
231235
assert flags.warn_error_options.silence == ["TestsConfigDeprecation"]
236+
237+
238+
input_model_without_event_time_sql = """
239+
{{ config(materialized='table') }}
240+
241+
select 1 as id, TIMESTAMP '2020-01-01 00:00:00-0' as event_time
242+
union all
243+
select 2 as id, TIMESTAMP '2020-01-02 00:00:00-0' as event_time
244+
union all
245+
select 3 as id, TIMESTAMP '2020-01-03 00:00:00-0' as event_time
246+
"""
247+
248+
microbatch_model_sql = """
249+
{{config(materialized='incremental', incremental_strategy='microbatch', unique_key='id', event_time='event_time', batch_size='day', begin=modules.datetime.datetime.now())}}
250+
SELECT id, event_time FROM {{ ref('input_model') }}
251+
"""
252+
253+
254+
class TestRequireAllWarningsHandledByWarnErrorBehaviorFlag:
255+
@pytest.fixture(scope="class")
256+
def models(self):
257+
return {
258+
"input_model.sql": input_model_without_event_time_sql,
259+
"microbatch_model.sql": microbatch_model_sql,
260+
}
261+
262+
def test_require_all_warnings_handed_by_warn_error_behavior_flag(self, project):
263+
# Setup the event catchers
264+
microbatch_warning_catcher = EventCatcher(event_to_catch=MicrobatchModelNoEventTimeInputs)
265+
microbatch_error_catcher = EventCatcher(event_to_catch=MainEncounteredError)
266+
dbt_runner = dbtRunner(
267+
callbacks=[microbatch_warning_catcher.catch, microbatch_error_catcher.catch]
268+
)
269+
270+
# Run the command without the behavior flag off
271+
project_flags = {
272+
"flags": {
273+
"send_anonymous_usage_stats": False,
274+
"require_all_warnings_handled_by_warn_error": False,
275+
}
276+
}
277+
update_config_file(project_flags, project.project_root, "dbt_project.yml")
278+
dbt_runner.invoke(["run", "--warn-error"])
279+
280+
assert len(microbatch_warning_catcher.caught_events) == 1
281+
assert len(microbatch_error_catcher.caught_events) == 0
282+
283+
# Reset the event catchers
284+
microbatch_warning_catcher.flush()
285+
microbatch_error_catcher.flush()
286+
287+
# Run the command with the behavior flag on
288+
project_flags = {
289+
"flags": {
290+
"send_anonymous_usage_stats": False,
291+
"require_all_warnings_handled_by_warn_error": True,
292+
}
293+
}
294+
update_config_file(project_flags, project.project_root, "dbt_project.yml")
295+
dbt_runner.invoke(["run", "--warn-error", "--log-format", "json"])
296+
297+
assert len(microbatch_warning_catcher.caught_events) == 0
298+
assert len(microbatch_error_catcher.caught_events) == 1

0 commit comments

Comments
 (0)