Alerting: Display error message in central state history view (#111445)

This commit is contained in:
Lauren
2025-09-23 15:55:53 +02:00
committed by GitHub
parent 42d64929d8
commit e4edb7b7bc
2 changed files with 54 additions and 0 deletions
@@ -0,0 +1,49 @@
import { render, screen } from 'test/test-utils';
import { TimeRange, dateTime } from '@grafana/data';
import { GrafanaAlertState } from 'app/types/unified-alerting-dto';
import { EventDetails } from './EventDetails';
// Mock hooks and modules used by EventDetails internals to avoid network/stateful behavior
jest.mock('../../../hooks/useCombinedRule', () => ({
useCombinedRule: () => ({ error: null, loading: false, result: { annotations: {} } }),
}));
jest.mock('../../../api/stateHistoryApi', () => ({
stateHistoryApi: {
useGetRuleHistoryQuery: () => ({ currentData: undefined, isLoading: false, isError: false, error: undefined }),
},
}));
jest.mock('../state-history/LokiStateHistory', () => ({
useFrameSubset: () => ({ frameSubset: [], frameTimeRange: undefined }),
}));
describe('EventDetails', () => {
it('renders error message row when current state is Error', () => {
const record = {
timestamp: Date.now(),
line: {
previous: GrafanaAlertState.Normal,
current: GrafanaAlertState.Error,
error: 'test error message',
labels: { instance: 'i-123' },
ruleUID: 'grafana/uid-1',
},
};
const timeRange: TimeRange = {
from: dateTime(0),
to: dateTime(1),
raw: { from: dateTime(0), to: dateTime(1) },
};
render(<EventDetails record={record} addFilter={jest.fn()} timeRange={timeRange} />);
const errorRow = screen.getByTestId('state-history-error');
expect(errorRow).toBeInTheDocument();
expect(errorRow).toHaveTextContent('Error message:');
expect(errorRow).toHaveTextContent('test error message');
});
});
@@ -6,6 +6,7 @@ import { DataFrame, DataFrameJSON, GrafanaTheme2, TimeRange } from '@grafana/dat
import { Trans, t } from '@grafana/i18n';
import { Icon, Stack, Text, useStyles2, useTheme2 } from '@grafana/ui';
import { CombinedRule } from 'app/types/unified-alerting';
import { GrafanaAlertState, mapStateWithReasonToBaseState } from 'app/types/unified-alerting-dto';
import { trackUseCentralHistoryExpandRow } from '../../../Analytics';
import { stateHistoryApi } from '../../../api/stateHistoryApi';
@@ -15,6 +16,7 @@ import { parsePromQLStyleMatcherLooseSafe } from '../../../utils/matchers';
import { parse } from '../../../utils/rule-id';
import { MetaText } from '../../MetaText';
import { AnnotationValue } from '../../rule-viewer/tabs/Details';
import { ErrorMessageRow } from '../state-history/ErrorMessageRow';
import { LogTimelineViewer } from '../state-history/LogTimelineViewer';
import { useFrameSubset } from '../state-history/LokiStateHistory';
import { LogRecord } from '../state-history/common';
@@ -72,6 +74,9 @@ export function EventDetails({ record, addFilter, timeRange }: EventDetailsProps
<StateTransition record={record} addFilter={addFilter} />
<ValueInTransition record={record} />
</Stack>
{mapStateWithReasonToBaseState(record.line.current) === GrafanaAlertState.Error && record.line.error && (
<ErrorMessageRow message={record.line.error} />
)}
<Annotations rule={rule} />
<StateVisualization ruleUID={ruleUID} timeRange={timeRange} labels={labelsInInstance ?? {}} />
</Stack>