Grammar: wrap in try/catch in case regex creation fails (#112595)
* Grammar: wrap in try/catch in case regex creation fails * Improve breadcrumbs
This commit is contained in:
@@ -2,7 +2,7 @@ import Prism, { Token } from 'prismjs';
|
||||
|
||||
import { createLogLine } from '../mocks/logRow';
|
||||
|
||||
import { generateLogGrammar } from './grammar';
|
||||
import { generateLogGrammar, generateTextMatchGrammar } from './grammar';
|
||||
|
||||
describe('generateLogGrammar', () => {
|
||||
function generateScenario(entry: string) {
|
||||
@@ -87,3 +87,41 @@ describe('generateLogGrammar', () => {
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('generateTextMatchGrammar', () => {
|
||||
const originalErr = console.error;
|
||||
beforeEach(() => {
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
});
|
||||
afterAll(() => {
|
||||
console.error = originalErr;
|
||||
});
|
||||
|
||||
test('Generates text match grammars for search words', () => {
|
||||
expect(generateTextMatchGrammar(['search', 'word'])).toEqual({
|
||||
'log-search-match': [/(?:search)/g, /(?:word)/g],
|
||||
});
|
||||
});
|
||||
|
||||
test('Generates text match grammars for search words and search', () => {
|
||||
expect(generateTextMatchGrammar(['search', 'word'], 'search text')).toEqual({
|
||||
'log-search-match': [/(?:search)/g, /(?:word)/g, /search text/gi],
|
||||
});
|
||||
});
|
||||
|
||||
test('Generates text match grammars for regex search words', () => {
|
||||
expect(generateTextMatchGrammar(['(?i)(TRACE|DEBUG|INFO|WARN|ERROR|OTHER)'])).toEqual({
|
||||
'log-search-match': [/(?:(TRACE|DEBUG|INFO|WARN|ERROR|OTHER))/gi],
|
||||
});
|
||||
});
|
||||
|
||||
test('Does not throw when the regular expression cannot be parsed correctly', () => {
|
||||
expect(generateTextMatchGrammar(['(?i)(?P<filtered_log_level>TRACE|DEBUG|INFO|WARN|ERROR|OTHER)'])).toEqual({});
|
||||
});
|
||||
|
||||
test('Handles mixed situations', () => {
|
||||
expect(generateTextMatchGrammar(['search', '(?i)(TRACE|DEBUG|INFO|WARN|ERROR|OTHER)'], 'word')).toEqual({
|
||||
'log-search-match': [/(?:search)/g, /(?:(TRACE|DEBUG|INFO|WARN|ERROR|OTHER))/gi, /word/gi],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,21 +52,30 @@ export const generateLogGrammar = (log: LogListModel) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const generateTextMatchGrammar = (
|
||||
highlightWords: string[] | undefined = [],
|
||||
search: string | undefined
|
||||
): Grammar => {
|
||||
export const generateTextMatchGrammar = (highlightWords: string[] | undefined = [], search?: string): Grammar => {
|
||||
/**
|
||||
* See:
|
||||
* - https://github.com/grafana/grafana/blob/96f1582c36f94cf4ac7621b7af86bc9e2ad626fb/public/app/features/logs/components/LogRowMessage.tsx#L67
|
||||
* - https://github.com/grafana/grafana/blob/96f1582c36f94cf4ac7621b7af86bc9e2ad626fb/packages/grafana-data/src/text/text.ts#L12
|
||||
*/
|
||||
const expressions = highlightWords.map((word) => {
|
||||
const { cleaned, flags } = parseFlags(cleanNeedle(word));
|
||||
return new RegExp(`(?:${cleaned})`, flags);
|
||||
});
|
||||
const expressions = highlightWords
|
||||
.map((word) => {
|
||||
const { cleaned, flags } = parseFlags(cleanNeedle(word));
|
||||
try {
|
||||
return new RegExp(`(?:${cleaned})`, flags);
|
||||
} catch (e) {
|
||||
console.error(`generateTextMatchGrammar: cannot generate regular expression from /${cleaned}/${flags}`, e);
|
||||
}
|
||||
return undefined;
|
||||
})
|
||||
.filter((expression) => expression !== undefined);
|
||||
|
||||
if (search) {
|
||||
expressions.push(new RegExp(escapeRegex(search), 'gi'));
|
||||
try {
|
||||
expressions.push(new RegExp(escapeRegex(search), 'gi'));
|
||||
} catch (e) {
|
||||
console.error(`generateTextMatchGrammar: cannot generate regular expression from /${search}/gi`, e);
|
||||
}
|
||||
}
|
||||
if (!expressions.length) {
|
||||
return {};
|
||||
|
||||
Reference in New Issue
Block a user