From 2d6ab9cbcc45a37c20acff5643a5887c22b908b7 Mon Sep 17 00:00:00 2001 From: Prabhanjan S Koushik Date: Tue, 17 Sep 2019 03:20:43 +0530 Subject: [PATCH] Fix-80080 Show more detailed error message for "Regex parse error" in search (#80495) * Added buildRegexParseError for better parsing error message * Fixed message * Review #1 changes * Changed error message as per review #2 * Review #3 changes * Review #4 changes --- .../search/node/ripgrepTextSearchEngine.ts | 17 +++++++++++++- .../test/node/textSearch.integrationTest.ts | 23 +++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts b/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts index 84d73b811cc52..554762af58bc5 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts @@ -125,7 +125,7 @@ export function rgErrorMsgForDisplay(msg: string): Maybe { const firstLine = lines[0].trim(); if (lines.some(l => startsWith(l, 'regex parse error'))) { - return new SearchError('Regex parse error', SearchErrorCode.regexParseError); + return new SearchError(buildRegexParseError(lines), SearchErrorCode.regexParseError); } const match = firstLine.match(/grep config error: unknown encoding: (.*)/); @@ -150,6 +150,21 @@ export function rgErrorMsgForDisplay(msg: string): Maybe { return undefined; } +export function buildRegexParseError(lines: string[]): string { + let errorMessage: string[] = ['Regex parse error']; + let pcre2ErrorLine = lines.filter(l => (startsWith(l, 'PCRE2:'))); + if (pcre2ErrorLine.length >= 1) { + let pcre2ErrorMessage = pcre2ErrorLine[0].replace('PCRE2:', ''); + if (pcre2ErrorMessage.indexOf(':') !== -1 && pcre2ErrorMessage.split(':').length >= 2) { + let pcre2ActualErrorMessage = pcre2ErrorMessage.split(':')[1]; + errorMessage.push(':' + pcre2ActualErrorMessage); + } + } + + return errorMessage.join(''); +} + + export class RipgrepParser extends EventEmitter { private remainder = ''; private isDone = false; diff --git a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts index ce38358933eea..6e8d77a82a5ba 100644 --- a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts +++ b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts @@ -376,7 +376,7 @@ suite('Search-integration', function () { }); }); - test('invalid regex', () => { + test('invalid regex case 1', () => { const config: ITextQuery = { type: QueryType.Text, folderQueries: ROOT_FOLDER_QUERY, @@ -387,11 +387,30 @@ suite('Search-integration', function () { throw new Error('expected fail'); }, err => { const searchError = deserializeSearchError(err.message); - assert.equal(searchError.message, 'Regex parse error'); + let regexParseErrorForUnclosedParenthesis = 'Regex parse error: unmatched closing parenthesis'; + assert.equal(searchError.message, regexParseErrorForUnclosedParenthesis); assert.equal(searchError.code, SearchErrorCode.regexParseError); }); }); + test('invalid regex case 2', () => { + const config: ITextQuery = { + type: QueryType.Text, + folderQueries: ROOT_FOLDER_QUERY, + contentPattern: { pattern: '(? { + throw new Error('expected fail'); + }, err => { + const searchError = deserializeSearchError(err.message); + let regexParseErrorForLookAround = 'Regex parse error: lookbehind assertion is not fixed length'; + assert.equal(searchError.message, regexParseErrorForLookAround); + assert.equal(searchError.code, SearchErrorCode.regexParseError); + }); + }); + + test('invalid glob', () => { const config: ITextQuery = { type: QueryType.Text,