Skip to content

Commit 970c061

Browse files
committed
Update error message for invalid measure / metric names
1 parent 3d347f2 commit 970c061

File tree

4 files changed

+173
-4
lines changed

4 files changed

+173
-4
lines changed

metricflow-semantics/metricflow_semantics/experimental/semantic_graph/attribute_resolution/sg_linkable_spec_resolver.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
from typing_extensions import override
99

1010
from metricflow_semantics.collection_helpers.syntactic_sugar import mf_first_item
11+
from metricflow_semantics.errors.error_classes import InvalidQueryException
1112
from metricflow_semantics.experimental.cache.mf_cache import ResultCache
1213
from metricflow_semantics.experimental.dataclass_helpers import fast_frozen_dataclass
1314
from metricflow_semantics.experimental.dsi.manifest_object_lookup import ManifestObjectLookup
14-
from metricflow_semantics.experimental.metricflow_exception import MetricflowInternalError
1515
from metricflow_semantics.experimental.mf_graph.graph_labeling import MetricflowGraphLabel
1616
from metricflow_semantics.experimental.mf_graph.path_finding.pathfinder import MetricflowPathfinder
1717
from metricflow_semantics.experimental.ordered_set import FrozenOrderedSet, MutableOrderedSet
@@ -163,9 +163,10 @@ def get_common_set(
163163
for label in node_labels:
164164
matching_nodes = self._semantic_graph.nodes_with_labels(label)
165165
if len(matching_nodes) != 1:
166-
raise MetricflowInternalError(
166+
raise InvalidQueryException(
167167
LazyFormat(
168-
"Did not find exactly 1 node in the semantic graph for the given label",
168+
"The given name is not valid. Please check that it matches one specified in the manifest.",
169+
element_name=mf_first_item(label_to_references[label]).element_name,
169170
label=label,
170171
associated_references=label_to_references.get(label),
171172
matching_nodes=matching_nodes,

metricflow-semantics/tests_metricflow_semantics/experimental/semantic_graph/resolver/test_sg_resolver_output.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
from _pytest.fixtures import FixtureRequest
77
from dbt_semantic_interfaces.protocols import SemanticManifest
88
from dbt_semantic_interfaces.references import MeasureReference, MetricReference
9+
from metricflow_semantics.errors.error_classes import InvalidQueryException
910
from metricflow_semantics.model.linkable_element_property import GroupByItemProperty
1011
from metricflow_semantics.model.semantics.element_filter import GroupByItemSetFilter
1112
from metricflow_semantics.model.semantics.linkable_element_set_base import BaseGroupByItemSet
1213
from metricflow_semantics.test_helpers.config_helpers import MetricFlowTestConfiguration
1314

15+
from tests_metricflow.snapshot_utils import assert_str_snapshot_equal
1416
from tests_metricflow_semantics.experimental.semantic_graph.sg_fixtures import SemanticGraphTestFixture
1517
from tests_metricflow_semantics.experimental.semantic_graph.sg_tester import SemanticGraphTester
1618

@@ -91,3 +93,17 @@ def test_set_filtering_for_distinct_values_query(sg_tester: SemanticGraphTester)
9193
complete_set=complete_set,
9294
filtered_set_callable=lambda set_filter: sg_tester.sg_resolver.get_set_for_distinct_values_query(set_filter),
9395
)
96+
97+
98+
def test_invalid_metric(
99+
request: FixtureRequest, mf_test_configuration: MetricFlowTestConfiguration, sg_tester: SemanticGraphTester
100+
) -> None:
101+
"""Check the exception associated with an invalid metric name."""
102+
with pytest.raises(InvalidQueryException) as exc_info:
103+
sg_tester.sg_resolver.get_common_set(metric_references=(MetricReference("invalid_metric"),))
104+
105+
assert_str_snapshot_equal(
106+
request=request,
107+
mf_test_configuration=mf_test_configuration,
108+
snapshot_str=str(exc_info.value),
109+
)
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
test_name: test_invalid_metric
2+
test_filename: test_sg_resolver_output.py
3+
docstring:
4+
Check the exception associated with an invalid metric name.
5+
---
6+
The given name is not valid. Please check that it matches one specified in the manifest.
7+
element_name: invalid_metric
8+
label: MetricLabel(metric_name='invalid_metric')
9+
associated_references: {MetricReference(element_name='invalid_metric')}
10+
matching_nodes: {}
11+
measure_nodes:
12+
{
13+
Measure(identity_verifications),
14+
Measure(visits),
15+
Measure(visitors),
16+
Measure(views),
17+
Measure(bookings),
18+
Measure(instant_bookings),
19+
Measure(booking_value),
20+
Measure(max_booking_value),
21+
Measure(min_booking_value),
22+
Measure(bookers),
23+
Measure(average_booking_value),
24+
Measure(referred_bookings),
25+
Measure(median_booking_value),
26+
Measure(booking_value_p99),
27+
Measure(discrete_booking_value_p99),
28+
Measure(approximate_continuous_booking_value_p99),
29+
Measure(approximate_discrete_booking_value_p99),
30+
Measure(booking_payments),
31+
Measure(account_balance),
32+
Measure(total_account_balance_first_day),
33+
Measure(current_account_balance_by_user),
34+
Measure(total_account_balance_first_day_of_month),
35+
Measure(new_users),
36+
Measure(archived_users),
37+
Measure(buys),
38+
Measure(buyers),
39+
Measure(buys_month),
40+
Measure(txn_revenue),
41+
Measure(listings),
42+
Measure(largest_listing),
43+
Measure(smallest_listing),
44+
}
45+
metric_nodes:
46+
{
47+
BaseMetric(bookings),
48+
BaseMetric(average_booking_value),
49+
BaseMetric(instant_bookings),
50+
BaseMetric(booking_value),
51+
BaseMetric(max_booking_value),
52+
BaseMetric(min_booking_value),
53+
BaseMetric(instant_booking_value),
54+
BaseMetric(average_instant_booking_value),
55+
BaseMetric(booking_value_for_non_null_listing_id),
56+
BaseMetric(bookers),
57+
BaseMetric(booking_payments),
58+
BaseMetric(views),
59+
BaseMetric(listings),
60+
BaseMetric(lux_listings),
61+
BaseMetric(smallest_listing),
62+
BaseMetric(largest_listing),
63+
BaseMetric(identity_verifications),
64+
BaseMetric(revenue),
65+
BaseMetric(trailing_2_months_revenue),
66+
BaseMetric(revenue_all_time),
67+
BaseMetric(every_two_days_bookers),
68+
BaseMetric(revenue_mtd),
69+
DerivedMetric(booking_fees),
70+
DerivedMetric(booking_fees_per_booker),
71+
DerivedMetric(booking_fees_last_week_per_booker_this_week),
72+
DerivedMetric(views_times_booking_value),
73+
DerivedMetric(bookings_per_booker),
74+
DerivedMetric(bookings_per_view),
75+
DerivedMetric(bookings_per_listing),
76+
DerivedMetric(bookings_per_dollar),
77+
BaseMetric(total_account_balance_first_day),
78+
BaseMetric(current_account_balance_by_user),
79+
DerivedMetric(instant_booking_fraction_of_max_value),
80+
DerivedMetric(lux_booking_fraction_of_max_value),
81+
DerivedMetric(lux_booking_value_rate_expr),
82+
DerivedMetric(instant_booking_value_ratio),
83+
DerivedMetric(instant_lux_booking_value_rate),
84+
DerivedMetric(regional_starting_balance_ratios),
85+
DerivedMetric(double_counted_delayed_bookings),
86+
BaseMetric(referred_bookings),
87+
DerivedMetric(non_referred_bookings_pct),
88+
DerivedMetric(booking_value_sub_instant),
89+
DerivedMetric(booking_value_sub_instant_add_10),
90+
DerivedMetric(bookings_per_lux_listing_derived),
91+
DerivedMetric(instant_plus_non_referred_bookings_pct),
92+
DerivedMetric(trailing_2_months_revenue_sub_10),
93+
DerivedMetric(booking_value_per_view),
94+
BaseMetric(median_booking_value),
95+
BaseMetric(booking_value_p99),
96+
BaseMetric(discrete_booking_value_p99),
97+
BaseMetric(approximate_continuous_booking_value_p99),
98+
BaseMetric(approximate_discrete_booking_value_p99),
99+
DerivedMetric(bookings_growth_2_weeks),
100+
BaseMetric(bookings_all_time),
101+
DerivedMetric(bookings_all_time_at_start_of_month),
102+
DerivedMetric(bookings_growth_since_start_of_month),
103+
DerivedMetric(bookings_since_start_of_month),
104+
DerivedMetric(bookings_month_start_compared_to_1_month_prior),
105+
DerivedMetric(bookings_5_day_lag),
106+
DerivedMetric(every_2_days_bookers_2_days_ago),
107+
BaseMetric(bookings_join_to_time_spine),
108+
BaseMetric(visit_buy_conversion_rate_7days),
109+
BaseMetric(visit_buy_conversion_rate),
110+
BaseMetric(visit_buy_conversions),
111+
BaseMetric(visit_buy_conversion_rate_with_monthly_conversion),
112+
BaseMetric(visit_buy_conversion_rate_by_session),
113+
BaseMetric(bookings_fill_nulls_with_0_without_time_spine),
114+
BaseMetric(bookings_fill_nulls_with_0),
115+
BaseMetric(instant_bookings_with_measure_filter),
116+
BaseMetric(bookings_join_to_time_spine_with_tiered_filters),
117+
BaseMetric(every_two_days_bookers_fill_nulls_with_0),
118+
DerivedMetric(bookings_growth_2_weeks_fill_nulls_with_0),
119+
DerivedMetric(bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset),
120+
DerivedMetric(bookings_offset_once),
121+
DerivedMetric(bookings_offset_twice),
122+
DerivedMetric(bookings_offset_alien_day),
123+
DerivedMetric(bookings_at_start_of_month),
124+
DerivedMetric(booking_fees_since_start_of_month),
125+
DerivedMetric(bookings_1_month_ago),
126+
DerivedMetric(bookings_mom),
127+
DerivedMetric(derived_bookings_0),
128+
DerivedMetric(derived_bookings_1),
129+
DerivedMetric(twice_bookings_fill_nulls_with_0_without_time_spine),
130+
DerivedMetric(nested_fill_nulls_without_time_spine),
131+
BaseMetric(visit_buy_conversion_rate_7days_fill_nulls_with_0),
132+
BaseMetric(active_listings),
133+
DerivedMetric(popular_listing_bookings_per_booker),
134+
DerivedMetric(derived_shared_alias_1a),
135+
DerivedMetric(derived_shared_alias_1b),
136+
DerivedMetric(derived_shared_alias_2),
137+
DerivedMetric(bookings_offset_one_alien_day),
138+
DerivedMetric(bookings_alien_day_over_alien_day),
139+
BaseMetric(trailing_7_days_bookings),
140+
DerivedMetric(trailing_7_days_bookings_offset_1_week),
141+
BaseMetric(subdaily_cumulative_window_metric),
142+
BaseMetric(subdaily_cumulative_grain_to_date_metric),
143+
BaseMetric(archived_users),
144+
DerivedMetric(subdaily_offset_window_metric),
145+
DerivedMetric(subdaily_offset_grain_to_date_metric),
146+
BaseMetric(subdaily_join_to_time_spine_metric),
147+
BaseMetric(simple_subdaily_metric_default_day),
148+
BaseMetric(simple_subdaily_metric_default_hour),
149+
BaseMetric(archived_users_join_to_time_spine),
150+
BaseMetric(total_account_balance_first_day_of_month),
151+
BaseMetric(new_users),
152+
}

tests_metricflow/snapshot_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ def assert_sql_snapshot_equal(
123123
def assert_str_snapshot_equal( # type: ignore[misc]
124124
request: FixtureRequest,
125125
mf_test_configuration: MetricFlowTestConfiguration,
126-
snapshot_id: str,
127126
snapshot_str: str,
127+
snapshot_id: str = "result",
128128
snapshot_file_extension: str = ".txt",
129129
sql_engine: Optional[SqlEngine] = None,
130130
expectation_description: Optional[str] = None,

0 commit comments

Comments
 (0)