Skip to content

Commit 202bea3

Browse files
shrutipatel31facebook-github-bot
authored andcommitted
Include exception message in ErrorAnalysisCard subtitle (facebook#4982)
Summary: Currently, the subtitle only shows a generic message like "AnalysisNotApplicableStateError encountered while computing ParallelCoordinatesPlot." Show the actual exception message, such as "AnalysisNotApplicableStateError: Experiment has no trials", providing immediate context. The exception message can now be displayed in the ErrorAnalysisCard subtitle, allowing users to immediately see the reasoning (e.g., why an analysis is not applicable). Reviewed By: bernardbeckerman Differential Revision: D94617700
1 parent 1054802 commit 202bea3

3 files changed

Lines changed: 67 additions & 7 deletions

File tree

ax/analysis/analysis.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,21 @@ def error_card_from_analysis_e(
206206
analysis_name = analysis_e.analysis.__class__.__name__
207207
exception_name = analysis_e.exception.__class__.__name__
208208

209+
# Include the exception message in the subtitle if available, so users can
210+
# see the reasoning in the error card.
211+
subtitle = (
212+
f"{exception_name}: {exception_message}"
213+
if (exception_message := str(analysis_e.exception))
214+
else f"{exception_name} encountered while computing {analysis_name}."
215+
)
216+
217+
tb = analysis_e.tb_str()
218+
blob = f"{subtitle}\n\n{tb}" if tb else subtitle
219+
209220
return ErrorAnalysisCard(
210221
name=analysis_name,
211222
title=f"{analysis_name} Error",
212-
subtitle=f"{exception_name} encountered while computing {analysis_name}.",
223+
subtitle=subtitle,
213224
df=pd.DataFrame(),
214-
blob=analysis_e.tb_str() or "",
225+
blob=blob,
215226
)

ax/analysis/tests/test_analysis.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
#
3+
# This source code is licensed under the MIT license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
# pyre-strict
7+
8+
from ax.analysis.analysis import AnalysisE, error_card_from_analysis_e
9+
from ax.analysis.plotly.parallel_coordinates import ParallelCoordinatesPlot
10+
from ax.utils.common.testutils import TestCase
11+
12+
13+
class AnalysisTest(TestCase):
14+
def test_error_card_from_analysis_e_with_message(self) -> None:
15+
# Setup: create an AnalysisE with an exception that has a message.
16+
analysis_e = AnalysisE(
17+
message="test",
18+
exception=ValueError("something went wrong"),
19+
analysis=ParallelCoordinatesPlot(),
20+
)
21+
22+
# Execute: generate the error card.
23+
card = error_card_from_analysis_e(analysis_e)
24+
25+
# Assert: subtitle and blob contain the exception message.
26+
self.assertEqual(card.name, "ParallelCoordinatesPlot")
27+
self.assertEqual(card.title, "ParallelCoordinatesPlot Error")
28+
self.assertEqual(card.subtitle, "ValueError: something went wrong")
29+
self.assertIn("ValueError: something went wrong", card.blob)
30+
31+
def test_error_card_from_analysis_e_without_message(self) -> None:
32+
# Setup: create an AnalysisE with an exception that has no message.
33+
analysis_e = AnalysisE(
34+
message="test",
35+
exception=ValueError(),
36+
analysis=ParallelCoordinatesPlot(),
37+
)
38+
39+
# Execute: generate the error card.
40+
card = error_card_from_analysis_e(analysis_e)
41+
42+
# Assert: subtitle and blob use the fallback text.
43+
expected = "ValueError encountered while computing ParallelCoordinatesPlot."
44+
self.assertEqual(card.name, "ParallelCoordinatesPlot")
45+
self.assertEqual(card.title, "ParallelCoordinatesPlot Error")
46+
self.assertEqual(card.subtitle, expected)
47+
self.assertIn(expected, card.blob)

ax/api/tests/test_client.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from ax.api.protocols.metric import IMetric
2424
from ax.api.protocols.runner import IRunner
2525
from ax.api.types import TParameterization
26-
from ax.core.analysis_card import AnalysisCard
2726
from ax.core.data import Data
2827
from ax.core.experiment import Experiment
2928
from ax.core.map_metric import MapMetric
@@ -1278,14 +1277,17 @@ def test_compute_analyses(self) -> None:
12781277
self.assertEqual(len(cards), 1)
12791278
self.assertEqual(cards[0].name, "ParallelCoordinatesPlot")
12801279
self.assertEqual(cards[0].title, "ParallelCoordinatesPlot Error")
1281-
self.assertEqual(
1280+
self.assertIn(
1281+
"AnalysisNotApplicableStateError",
1282+
cards[0].subtitle,
1283+
)
1284+
self.assertIn(
1285+
"Experiment has no trials",
12821286
cards[0].subtitle,
1283-
"AnalysisNotApplicableStateError encountered while computing "
1284-
"ParallelCoordinatesPlot.",
12851287
)
12861288
self.assertIn(
12871289
"Experiment has no trials",
1288-
assert_is_instance(cards[0], AnalysisCard).blob,
1290+
cards[0].blob,
12891291
)
12901292

12911293
for trial_index, _ in client.get_next_trials(max_trials=1).items():

0 commit comments

Comments
 (0)