Alerting: Catch alert rule search exceptions (#91788)

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

View File

@ -273,9 +273,25 @@ describe('filterRules', function () {
const ruleQuery = '[alongnameinthefirstgroup][thishas spaces][somethingelse]';
const namespaceQuery = 'foo|bar';
const groupQuery = 'some|group';
const freeForm = '.+';
const performFilter = () =>
filterRules([ns], getFilter({ groupName: groupQuery, ruleName: ruleQuery, namespace: namespaceQuery }));
expect(performFilter).not.toThrow();
expect(() =>
filterRules(
[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 { isPromAlertingRuleState, PromRuleType, RulerGrafanaRuleDTO } from 'app/types/unified-alerting-dto';
import { logError } from '../Analytics';
import { applySearchFilterToQuery, getSearchFilterFromQuery, RulesFilter } from '../search/rulesSearchParser';
import { labelsMatchMatchers, matcherToMatcherField } from '../utils/alertmanager';
import { Annotation } from '../utils/constants';
@ -28,6 +29,8 @@ import { useURLSearchParams } from './useURLSearchParams';
const MAX_NEEDLE_SIZE = 25;
const INFO_THRESHOLD = Infinity;
const SEARCH_FAILED_ERR = new Error('Failed to search rules');
/**
* Escape query strings so that regex characters don't interfere
* 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.
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) => {