Skip to content

Commit 8cc8a33

Browse files
authored
raise errors if run dag fails (#1251)
1 parent 577fb29 commit 8cc8a33

4 files changed

Lines changed: 25 additions & 7 deletions

File tree

sqlmesh/cli/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,9 @@ def plan(ctx: click.Context, environment: t.Optional[str] = None, **kwargs: t.An
299299
def run(ctx: click.Context, environment: t.Optional[str] = None, **kwargs: t.Any) -> None:
300300
"""Evaluates the DAG of models using the built-in scheduler."""
301301
context = ctx.obj
302-
context.run(environment, **kwargs)
302+
success = context.run(environment, **kwargs)
303+
if not success:
304+
raise click.ClickException("Run DAG Failed. See output for details.")
303305

304306

305307
@cli.command("invalidate")

sqlmesh/core/context.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ def run(
394394
execution_time: t.Optional[TimeLike] = None,
395395
skip_janitor: bool = False,
396396
ignore_cron: bool = False,
397-
) -> None:
397+
) -> bool:
398398
"""Run the entire dag through the scheduler.
399399
400400
Args:
@@ -404,13 +404,16 @@ def run(
404404
execution_time: The date/time time reference to use for execution time. Defaults to now.
405405
skip_janitor: Whether to skip the janitor task.
406406
ignore_cron: Whether to ignore the model's cron schedule and run all available missing intervals.
407+
408+
Returns:
409+
True if the run was successful, False otherwise.
407410
"""
408411
environment = environment or c.PROD
409412
self.notification_target_manager.notify(
410413
NotificationEvent.RUN_START, environment=environment
411414
)
412415
try:
413-
self.scheduler(environment=environment).run(
416+
success = self.scheduler(environment=environment).run(
414417
environment,
415418
start=start,
416419
end=end,
@@ -422,11 +425,21 @@ def run(
422425
NotificationEvent.RUN_FAILURE, traceback.format_exc()
423426
)
424427
raise e
425-
self.notification_target_manager.notify(NotificationEvent.RUN_END, environment=environment)
428+
if success:
429+
self.notification_target_manager.notify(
430+
NotificationEvent.RUN_END, environment=environment
431+
)
432+
else:
433+
self.notification_target_manager.notify(
434+
NotificationEvent.RUN_FAILURE, environment=environment
435+
)
436+
return success
426437

427438
if not skip_janitor and environment.lower() == c.PROD:
428439
self._run_janitor()
429440

441+
return success
442+
430443
@t.overload
431444
def get_model(
432445
self, model_or_snapshot: ModelOrSnapshot, raise_if_missing: Literal[True] = True

sqlmesh/magics.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from sqlmesh.core.model import load_sql_based_model
2323
from sqlmesh.core.test import ModelTestMetadata, get_all_model_tests
2424
from sqlmesh.utils import sqlglot_dialects, yaml
25-
from sqlmesh.utils.errors import MagicError, MissingContextException
25+
from sqlmesh.utils.errors import MagicError, MissingContextException, SQLMeshError
2626

2727
CONTEXT_VARIABLE_NAMES = [
2828
"context",
@@ -358,14 +358,16 @@ def run_dag(self, line: str) -> None:
358358
console = self._context.console
359359
self._context.console = get_console(display=self.display)
360360

361-
self._context.run(
361+
success = self._context.run(
362362
args.environment,
363363
start=args.start,
364364
end=args.end,
365365
skip_janitor=args.skip_janitor,
366366
ignore_cron=args.ignore_cron,
367367
)
368368
self._context.console = console
369+
if not success:
370+
raise SQLMeshError("Error Running DAG. Check logs for details.")
369371

370372
@magic_arguments()
371373
@argument("model", type=str, help="The model.")

tests/core/test_context.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def test_diff(sushi_context: Context, mocker: MockerFixture):
184184
mock_console = mocker.Mock()
185185
sushi_context.console = mock_console
186186
yesterday = yesterday_ds()
187-
sushi_context.run(start=yesterday, end=yesterday)
187+
success = sushi_context.run(start=yesterday, end=yesterday)
188188

189189
plan_evaluator = BuiltInPlanEvaluator(
190190
sushi_context.state_sync, sushi_context.snapshot_evaluator
@@ -198,6 +198,7 @@ def test_diff(sushi_context: Context, mocker: MockerFixture):
198198
sushi_context.upsert_model("sushi.customers", query=parse_one("select 1 as customer_id"))
199199
sushi_context.diff("test")
200200
assert mock_console.show_model_difference_summary.called
201+
assert success
201202

202203

203204
def test_evaluate_limit():

0 commit comments

Comments
 (0)