3
0
mirror of https://github.com/grafana/grafana.git synced 2025-02-13 09:05:45 -06:00

Alerting: Catch alert rule search exceptions ()

catch search exceptions and prevent from bubbling
This commit is contained in:
Gilles De Mey 2024-08-12 12:13:26 +02:00 committed by GitHub
parent 82d051f336
commit 15f2b08f00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 4 deletions
public/app/features/alerting/unified/hooks

View File

@ -273,9 +273,25 @@ describe('filterRules', function () {
const ruleQuery = '[alongnameinthefirstgroup][thishas spaces][somethingelse]'; const ruleQuery = '[alongnameinthefirstgroup][thishas spaces][somethingelse]';
const namespaceQuery = 'foo|bar'; const namespaceQuery = 'foo|bar';
const groupQuery = 'some|group'; const groupQuery = 'some|group';
const freeForm = '.+';
const performFilter = () => expect(() =>
filterRules([ns], getFilter({ groupName: groupQuery, ruleName: ruleQuery, namespace: namespaceQuery })); filterRules(
expect(performFilter).not.toThrow(); [ns],
getFilter({ groupName: groupQuery, ruleName: ruleQuery, namespace: namespaceQuery, freeFormWords: [freeForm] })
)
).not.toThrow();
});
// these test may same to be the same as the one above but it tests different edge-cases
it('does not crash with other regex values', () => {
const rules = [mockCombinedRule({ name: 'rule' })];
const ns = mockCombinedRuleNamespace({
name: 'namespace',
groups: [mockCombinedRuleGroup('group', rules)],
});
expect(() => filterRules([ns], getFilter({ freeFormWords: ['.+'] }))).not.toThrow();
}); });
}); });

View File

@ -8,6 +8,7 @@ import { Matcher } from 'app/plugins/datasource/alertmanager/types';
import { CombinedRuleGroup, CombinedRuleNamespace, Rule } from 'app/types/unified-alerting'; import { CombinedRuleGroup, CombinedRuleNamespace, Rule } from 'app/types/unified-alerting';
import { isPromAlertingRuleState, PromRuleType, RulerGrafanaRuleDTO } from 'app/types/unified-alerting-dto'; import { isPromAlertingRuleState, PromRuleType, RulerGrafanaRuleDTO } from 'app/types/unified-alerting-dto';
import { logError } from '../Analytics';
import { applySearchFilterToQuery, getSearchFilterFromQuery, RulesFilter } from '../search/rulesSearchParser'; import { applySearchFilterToQuery, getSearchFilterFromQuery, RulesFilter } from '../search/rulesSearchParser';
import { labelsMatchMatchers, matcherToMatcherField } from '../utils/alertmanager'; import { labelsMatchMatchers, matcherToMatcherField } from '../utils/alertmanager';
import { Annotation } from '../utils/constants'; import { Annotation } from '../utils/constants';
@ -28,6 +29,8 @@ import { useURLSearchParams } from './useURLSearchParams';
const MAX_NEEDLE_SIZE = 25; const MAX_NEEDLE_SIZE = 25;
const INFO_THRESHOLD = Infinity; const INFO_THRESHOLD = Infinity;
const SEARCH_FAILED_ERR = new Error('Failed to search rules');
/** /**
* Escape query strings so that regex characters don't interfere * Escape query strings so that regex characters don't interfere
* with uFuzzy search methods. * with uFuzzy search methods.
@ -160,7 +163,20 @@ export const filterRules = (
} }
// If a namespace and group have rules that match the rules filters then keep them. // If a namespace and group have rules that match the rules filters then keep them.
return filteredNamespaces.reduce<CombinedRuleNamespace[]>(reduceNamespaces(filterState), []); const filteredRuleNamespaces: CombinedRuleNamespace[] = [];
try {
const matches = filteredNamespaces.reduce<CombinedRuleNamespace[]>(reduceNamespaces(filterState), []);
matches.forEach((match) => {
filteredRuleNamespaces.push(match);
});
} catch {
logError(SEARCH_FAILED_ERR, {
search: JSON.stringify(filterState),
});
}
return filteredRuleNamespaces;
}; };
const reduceNamespaces = (filterState: RulesFilter) => { const reduceNamespaces = (filterState: RulesFilter) => {