diff --git a/dvc/repo/plots/template.py b/dvc/repo/plots/template.py index 01f9a85c6..7713c0d8c 100644 --- a/dvc/repo/plots/template.py +++ b/dvc/repo/plots/template.py @@ -12,6 +12,10 @@ class TemplateNotFoundError(DvcException): super().__init__(f"Template '{path}' not found.") +class BadTemplateError(DvcException): + pass + + class NoFieldInDataError(DvcException): def __init__(self, field_name): super().__init__( @@ -39,6 +43,12 @@ class Template: def render(self, data, props=None): props = props or {} + if self.METRIC_DATA_ANCHOR not in self.content: + raise BadTemplateError( + f"Template '{self.filename}' is not using " + f"'{self.METRIC_DATA_ANCHOR}' anchor" + ) + if props.get("x"): Template._check_field_exists(data, props.get("x")) if props.get("y"): diff --git a/tests/func/plots/test_plots.py b/tests/func/plots/test_plots.py index 33a910026..0e7427c76 100644 --- a/tests/func/plots/test_plots.py +++ b/tests/func/plots/test_plots.py @@ -16,7 +16,11 @@ from dvc.repo.plots.data import ( PlotMetricTypeError, YAMLPlotData, ) -from dvc.repo.plots.template import NoFieldInDataError, TemplateNotFoundError +from dvc.repo.plots.template import ( + BadTemplateError, + NoFieldInDataError, + TemplateNotFoundError, +) def _write_csv(metric, filename, header=True): @@ -405,6 +409,23 @@ def test_should_raise_on_no_template(tmp_dir, dvc, run_copy_metrics): dvc.plots.show("metric.json", props=props) +def test_bad_template(tmp_dir, dvc, run_copy_metrics): + metric = [{"val": 2}, {"val": 3}] + _write_json(tmp_dir, metric, "metric_t.json") + run_copy_metrics( + "metric_t.json", + "metric.json", + plots_no_cache=["metric.json"], + commit="first run", + ) + + tmp_dir.gen("template.json", json.dumps({"a": "b", "c": "d"})) + + with pytest.raises(BadTemplateError): + props = {"template": "template.json"} + dvc.plots.show("metric.json", props=props) + + def test_plot_wrong_metric_type(tmp_dir, scm, dvc, run_copy_metrics): tmp_dir.gen("metric_t.txt", "some text") run_copy_metrics(