Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vscode.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandeep Somavarapu <sasomava@microsoft.com>2022-05-02 15:05:30 +0300
committerSandeep Somavarapu <sasomava@microsoft.com>2022-05-02 15:05:30 +0300
commit05b9eddd4bdd3eacab8c4d5ee195ce11b05c5d0f (patch)
tree4e0c7cc3d869ffbeb30908bda31687d665f77750
parent1cca784e1fcd5144e29b0ee7da7d6a0e5dd00b1b (diff)
- override extension type of extensions under dev from existing extensions
- validate after updating the type
-rw-r--r--scripts/test-integration.bat4
-rwxr-xr-xscripts/test-integration.sh4
-rw-r--r--scripts/test-remote-integration.bat4
-rwxr-xr-xscripts/test-remote-integration.sh4
-rw-r--r--scripts/test-web-integration.bat2
-rwxr-xr-xscripts/test-web-integration.sh4
-rw-r--r--src/vs/platform/extensionManagement/common/extensionsScannerService.ts59
-rw-r--r--src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts28
8 files changed, 61 insertions, 48 deletions
diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat
index 309bfd91e33..0260a781d8d 100644
--- a/scripts/test-integration.bat
+++ b/scripts/test-integration.bat
@@ -74,7 +74,7 @@ if %errorlevel% neq 0 exit /b %errorlevel%
echo.
echo ### TypeScript tests
-call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\typescript-language-features\test-workspace --extensionDevelopmentPath=%~dp0\..\extensions\typescript-language-features --extensionTestsPath=%~dp0\..\extensions\typescript-language-features\out\test\unit --enable-proposed-api=vscode.typescript-language-features %API_TESTS_EXTRA_ARGS%
+call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\typescript-language-features\test-workspace --extensionDevelopmentPath=%~dp0\..\extensions\typescript-language-features --extensionTestsPath=%~dp0\..\extensions\typescript-language-features\out\test\unit %API_TESTS_EXTRA_ARGS%
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
@@ -92,7 +92,7 @@ echo ### Git tests
for /f "delims=" %%i in ('node -p "require('fs').realpathSync.native(require('os').tmpdir())"') do set TEMPDIR=%%i
set GITWORKSPACE=%TEMPDIR%\git-%RANDOM%
mkdir %GITWORKSPACE%
-call "%INTEGRATION_TEST_ELECTRON_PATH%" %GITWORKSPACE% --extensionDevelopmentPath=%~dp0\..\extensions\git --extensionTestsPath=%~dp0\..\extensions\git\out\test --enable-proposed-api=vscode.git %API_TESTS_EXTRA_ARGS%
+call "%INTEGRATION_TEST_ELECTRON_PATH%" %GITWORKSPACE% --extensionDevelopmentPath=%~dp0\..\extensions\git --extensionTestsPath=%~dp0\..\extensions\git\out\test %API_TESTS_EXTRA_ARGS%
if %errorlevel% neq 0 exit /b %errorlevel%
echo.
diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh
index f0d239a470d..8ddfa7e9eae 100755
--- a/scripts/test-integration.sh
+++ b/scripts/test-integration.sh
@@ -93,7 +93,7 @@ kill_app
echo
echo "### TypeScript tests"
echo
-"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/typescript-language-features/test-workspace --enable-proposed-api=vscode.typescript-language-features --extensionDevelopmentPath=$ROOT/extensions/typescript-language-features --extensionTestsPath=$ROOT/extensions/typescript-language-features/out/test/unit $API_TESTS_EXTRA_ARGS
+"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/typescript-language-features/test-workspace --extensionDevelopmentPath=$ROOT/extensions/typescript-language-features --extensionTestsPath=$ROOT/extensions/typescript-language-features/out/test/unit $API_TESTS_EXTRA_ARGS
kill_app
echo
@@ -111,7 +111,7 @@ kill_app
echo
echo "### Git tests"
echo
-"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $(mktemp -d 2>/dev/null) --enable-proposed-api=vscode.git --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test $API_TESTS_EXTRA_ARGS
+"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test $API_TESTS_EXTRA_ARGS
kill_app
echo
diff --git a/scripts/test-remote-integration.bat b/scripts/test-remote-integration.bat
index 396737b831e..1c04b2e392c 100644
--- a/scripts/test-remote-integration.bat
+++ b/scripts/test-remote-integration.bat
@@ -64,10 +64,10 @@ if "%INTEGRATION_TEST_ELECTRON_PATH%"=="" (
set ELECTRON_ENABLE_STACK_DUMPING=1
:: Tests in the extension host running from built version (both client and server)
- call "%INTEGRATION_TEST_ELECTRON_PATH%" --folder-uri=%REMOTE_VSCODE%/vscode-api-tests/testWorkspace --extensionDevelopmentPath=%REMOTE_VSCODE%/vscode-api-tests --extensionTestsPath=%REMOTE_VSCODE%/vscode-api-tests/out/singlefolder-tests %API_TESTS_EXTRA_ARGS% --extensions-dir=%EXT_PATH% --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests --enable-proposed-api=vscode.image-preview
+ call "%INTEGRATION_TEST_ELECTRON_PATH%" --folder-uri=%REMOTE_VSCODE%/vscode-api-tests/testWorkspace --extensionDevelopmentPath=%REMOTE_VSCODE%/vscode-api-tests --extensionTestsPath=%REMOTE_VSCODE%/vscode-api-tests/out/singlefolder-tests %API_TESTS_EXTRA_ARGS% --extensions-dir=%EXT_PATH% --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests
if %errorlevel% neq 0 exit /b %errorlevel%
- call "%INTEGRATION_TEST_ELECTRON_PATH%" --file-uri=%REMOTE_VSCODE%/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=%REMOTE_VSCODE%/vscode-api-tests --extensionTestsPath=%REMOTE_VSCODE%/vscode-api-tests/out/workspace-tests %API_TESTS_EXTRA_ARGS% --extensions-dir=%EXT_PATH% --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests --enable-proposed-api=vscode.image-preview
+ call "%INTEGRATION_TEST_ELECTRON_PATH%" --file-uri=%REMOTE_VSCODE%/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=%REMOTE_VSCODE%/vscode-api-tests --extensionTestsPath=%REMOTE_VSCODE%/vscode-api-tests/out/workspace-tests %API_TESTS_EXTRA_ARGS% --extensions-dir=%EXT_PATH% --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests
if %errorlevel% neq 0 exit /b %errorlevel%
)
diff --git a/scripts/test-remote-integration.sh b/scripts/test-remote-integration.sh
index 48f10d5b2c4..e2212317d3b 100755
--- a/scripts/test-remote-integration.sh
+++ b/scripts/test-remote-integration.sh
@@ -63,7 +63,7 @@ else
export ELECTRON_ENABLE_LOGGING=1
# Running from a build, we need to enable the vscode-test-resolver extension
- EXTRA_INTEGRATION_TEST_ARGUMENTS="--extensions-dir=$EXT_PATH --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests --enable-proposed-api=vscode.image-preview --enable-proposed-api=vscode.git --enable-proposed-api=vscode.markdown-language-features"
+ EXTRA_INTEGRATION_TEST_ARGUMENTS="--extensions-dir=$EXT_PATH --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests"
echo "Storing crash reports into '$VSCODECRASHDIR'."
echo "Storing log files into '$VSCODELOGSDIR'."
@@ -105,7 +105,7 @@ kill_app
echo
echo "### TypeScript tests"
echo
-"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS --folder-uri=$REMOTE_VSCODE/typescript-language-features/test-workspace --enable-proposed-api=vscode.typescript-language-features --extensionDevelopmentPath=$REMOTE_VSCODE/typescript-language-features --extensionTestsPath=$REMOTE_VSCODE/typescript-language-features/out/test/unit $API_TESTS_EXTRA_ARGS $EXTRA_INTEGRATION_TEST_ARGUMENTS
+"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS --folder-uri=$REMOTE_VSCODE/typescript-language-features/test-workspace --extensionDevelopmentPath=$REMOTE_VSCODE/typescript-language-features --extensionTestsPath=$REMOTE_VSCODE/typescript-language-features/out/test/unit $API_TESTS_EXTRA_ARGS $EXTRA_INTEGRATION_TEST_ARGUMENTS
kill_app
echo
diff --git a/scripts/test-web-integration.bat b/scripts/test-web-integration.bat
index 6f778843e05..99bb16b7d5e 100644
--- a/scripts/test-web-integration.bat
+++ b/scripts/test-web-integration.bat
@@ -68,5 +68,5 @@ echo ### Git tests
for /f "delims=" %%i in ('node -p "require('fs').realpathSync.native(require('os').tmpdir())"') do set TEMPDIR=%%i
set GITWORKSPACE=%TEMPDIR%\git-%RANDOM%
mkdir %GITWORKSPACE%
-call node .\test\integration\browser\out\index.js --workspacePath=%GITWORKSPACE% --extensionDevelopmentPath=.\extensions\git --extensionTestsPath=.\extensions\git\out\test --enable-proposed-api=vscode.git %*
+call node .\test\integration\browser\out\index.js --workspacePath=%GITWORKSPACE% --extensionDevelopmentPath=.\extensions\git --extensionTestsPath=.\extensions\git\out\test %*
if %errorlevel% neq 0 exit /b %errorlevel%
diff --git a/scripts/test-web-integration.sh b/scripts/test-web-integration.sh
index f1b6c7683ac..8f05929fdc4 100755
--- a/scripts/test-web-integration.sh
+++ b/scripts/test-web-integration.sh
@@ -63,10 +63,10 @@ node test/integration/browser/out/index.js --workspacePath $ROOT/extensions/emme
echo
echo "### Git tests"
echo
-node test/integration/browser/out/index.js --workspacePath $(mktemp -d 2>/dev/null) --enable-proposed-api=vscode.git --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test "$@"
+node test/integration/browser/out/index.js --workspacePath $(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test "$@"
echo
echo "### Ipynb tests"
echo
-node test/integration/browser/out/index.js --workspacePath $(mktemp -d 2>/dev/null) --enable-proposed-api=vscode.ipynb --extensionDevelopmentPath=$ROOT/extensions/ipynb --extensionTestsPath=$ROOT/extensions/ipynb/out/test "$@"
+node test/integration/browser/out/index.js --workspacePath $(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$ROOT/extensions/ipynb --extensionTestsPath=$ROOT/extensions/ipynb/out/test "$@"
diff --git a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts
index 8a8746587f1..93936e42335 100644
--- a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts
+++ b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts
@@ -23,7 +23,7 @@ import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { Metadata } from 'vs/platform/extensionManagement/common/extensionManagement';
-import { computeTargetPlatform, ExtensionKey, getExtensionId, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
+import { areSameExtensions, computeTargetPlatform, ExtensionKey, getExtensionId, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ExtensionType, ExtensionIdentifier, IExtensionManifest, TargetPlatform, IExtensionIdentifier, IRelaxedExtensionManifest, UNDEFINED_PUBLISHER, IExtensionDescription, BUILTIN_MANIFEST_CACHE_FILE, USER_MANIFEST_CACHE_FILE, MANIFEST_CACHE_FOLDER } from 'vs/platform/extensions/common/extensions';
import { validateExtensionManifest } from 'vs/platform/extensions/common/extensionValidator';
import { FileOperationResult, IFileService, toFileOperationResult } from 'vs/platform/files/common/files';
@@ -118,7 +118,7 @@ export interface IExtensionsScannerService {
scanAllExtensions(scanOptions: ScanOptions): Promise<IScannedExtension[]>;
scanSystemExtensions(scanOptions: ScanOptions): Promise<IScannedExtension[]>;
scanUserExtensions(scanOptions: ScanOptions): Promise<IScannedExtension[]>;
- scanExtensionsUnderDevelopment(scanOptions: ScanOptions): Promise<IScannedExtension[]>;
+ scanExtensionsUnderDevelopment(scanOptions: ScanOptions, existingExtensions: IScannedExtension[]): Promise<IScannedExtension[]>;
scanExistingExtension(extensionLocation: URI, extensionType: ExtensionType, scanOptions: ScanOptions): Promise<IScannedExtension | null>;
scanOneOrMultipleExtensions(extensionLocation: URI, extensionType: ExtensionType, scanOptions: ScanOptions): Promise<IScannedExtension[]>;
@@ -163,11 +163,11 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
}
async scanAllExtensions(scanOptions: ScanOptions): Promise<IScannedExtension[]> {
- const [system, user, development] = await Promise.all([
+ const [system, user] = await Promise.all([
this.scanSystemExtensions(scanOptions),
this.scanUserExtensions(scanOptions),
- this.scanExtensionsUnderDevelopment(scanOptions),
]);
+ const development = await this.scanExtensionsUnderDevelopment(scanOptions, [...system, ...user]);
return this.dedupExtensions([...system, ...user, ...development], await this.getTargetPlatform(), true);
}
@@ -189,10 +189,19 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
return extensions;
}
- async scanExtensionsUnderDevelopment(scanOptions: ScanOptions): Promise<IScannedExtension[]> {
+ async scanExtensionsUnderDevelopment(scanOptions: ScanOptions, existingExtensions: IScannedExtension[]): Promise<IScannedExtension[]> {
if (this.environmentService.isExtensionDevelopment && this.environmentService.extensionDevelopmentLocationURI) {
const extensions = (await Promise.all(this.environmentService.extensionDevelopmentLocationURI.filter(extLoc => extLoc.scheme === Schemas.file)
- .map(async extensionDevelopmentLocationURI => this.extensionsScanner.scanOneOrMultipleExtensions((await this.createExtensionScannerInput(extensionDevelopmentLocationURI, ExtensionType.User, true, scanOptions.language))))))
+ .map(async extensionDevelopmentLocationURI => {
+ const input = await this.createExtensionScannerInput(extensionDevelopmentLocationURI, ExtensionType.User, true, scanOptions.language, false /* do not validate */);
+ const extensions = await this.extensionsScanner.scanOneOrMultipleExtensions(input);
+ return extensions.map(extension => {
+ // Override the extension type from the existing extensions
+ extension.type = existingExtensions.find(e => areSameExtensions(e.identifier, extension.identifier))?.type ?? extension.type;
+ // Validate the extension
+ return this.extensionsScanner.validate(extension, input);
+ });
+ })))
.flat();
return this.applyScanOptions(extensions, scanOptions, true);
}
@@ -327,7 +336,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
}
}
- private async createExtensionScannerInput(location: URI, type: ExtensionType, excludeObsolete: boolean, language: string | undefined): Promise<ExtensionScannerInput> {
+ private async createExtensionScannerInput(location: URI, type: ExtensionType, excludeObsolete: boolean, language: string | undefined, validate: boolean = true): Promise<ExtensionScannerInput> {
const translations = await this.getTranslations(language ?? platform.language);
let mtime: number | undefined;
try {
@@ -343,6 +352,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
mtime,
type,
excludeObsolete,
+ validate,
this.productService.version,
this.productService.date,
this.productService.commit,
@@ -361,6 +371,7 @@ class ExtensionScannerInput {
public readonly mtime: number | undefined,
public readonly type: ExtensionType,
public readonly excludeObsolete: boolean,
+ public readonly validate: boolean,
public readonly productVersion: string,
public readonly productDate: string | undefined,
public readonly productCommit: string | undefined,
@@ -386,6 +397,7 @@ class ExtensionScannerInput {
&& a.mtime === b.mtime
&& a.type === b.type
&& a.excludeObsolete === b.excludeObsolete
+ && a.validate === b.validate
&& a.productVersion === b.productVersion
&& a.productDate === b.productDate
&& a.productCommit === b.productCommit
@@ -431,7 +443,7 @@ class ExtensionsScanner extends Disposable {
if (input.type === ExtensionType.User && basename(c.resource).indexOf('.') === 0) {
return null;
}
- const extensionScannerInput = new ExtensionScannerInput(c.resource, input.mtime, input.type, input.excludeObsolete, input.productVersion, input.productDate, input.productCommit, input.devMode, input.language, input.translations);
+ const extensionScannerInput = new ExtensionScannerInput(c.resource, input.mtime, input.type, input.excludeObsolete, input.validate, input.productVersion, input.productDate, input.productCommit, input.devMode, input.language, input.translations);
const extension = await this.scanExtension(extensionScannerInput);
return extension && !obsolete[ExtensionKey.create(extension).toString()] ? extension : null;
}));
@@ -440,7 +452,7 @@ class ExtensionsScanner extends Disposable {
return [];
}
- async scanOneOrMultipleExtensions(input: ExtensionScannerInput): Promise<IScannedExtension[]> {
+ async scanOneOrMultipleExtensions(input: ExtensionScannerInput): Promise<IRelaxedScannedExtension[]> {
try {
if (await this.fileService.exists(joinPath(input.location, 'package.json'))) {
const extension = await this.scanExtension(input);
@@ -468,16 +480,8 @@ class ExtensionsScanner extends Disposable {
const identifier = metadata?.id ? { id, uuid: metadata.id } : { id };
const type = metadata?.isSystem ? ExtensionType.System : input.type;
const isBuiltin = type === ExtensionType.System || !!metadata?.isBuiltin;
- const validations = validateExtensionManifest(input.productVersion, input.productDate, input.location, manifest, isBuiltin);
- let isValid = true;
- for (const [severity, message] of validations) {
- if (severity === Severity.Error) {
- isValid = false;
- this.logService.error(this.formatMessage(input.location, message));
- }
- }
manifest = await this.translateManifest(input.location, manifest, ExtensionScannerInput.createNlsConfiguration(input));
- return {
+ const extension = {
type,
identifier,
manifest,
@@ -485,9 +489,10 @@ class ExtensionsScanner extends Disposable {
isBuiltin,
targetPlatform: metadata?.targetPlatform ?? TargetPlatform.UNDEFINED,
metadata,
- isValid,
- validations
+ isValid: true,
+ validations: []
};
+ return input.validate ? this.validate(extension, input) : extension;
}
} catch (e) {
if (input.type !== ExtensionType.System) {
@@ -497,6 +502,20 @@ class ExtensionsScanner extends Disposable {
return null;
}
+ validate(extension: IRelaxedScannedExtension, input: ExtensionScannerInput): IRelaxedScannedExtension {
+ let isValid = true;
+ const validations = validateExtensionManifest(input.productVersion, input.productDate, input.location, extension.manifest, extension.isBuiltin);
+ for (const [severity, message] of validations) {
+ if (severity === Severity.Error) {
+ isValid = false;
+ this.logService.error(this.formatMessage(input.location, message));
+ }
+ }
+ extension.isValid = isValid;
+ extension.validations = validations;
+ return extension;
+ }
+
private async scanExtensionManifest(extensionLocation: URI): Promise<IScannedExtensionManifest | null> {
const manifestLocation = joinPath(extensionLocation, 'package.json');
let content;
diff --git a/src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts b/src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts
index f15839b061e..852ea7702e9 100644
--- a/src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts
+++ b/src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts
@@ -50,21 +50,15 @@ export class CachedExtensionScanner {
}
private async _scanInstalledExtensions(): Promise<{ system: IExtensionDescription[]; user: IExtensionDescription[]; development: IExtensionDescription[] }> {
- const language = platform.language;
-
- const builtinExtensions = this._extensionsScannerService.scanSystemExtensions({ language, useCache: true, checkControlFile: true })
- .then(scannedExtensions => scannedExtensions.map(e => toExtensionDescription(e, false)));
-
- const userExtensions = this._extensionsScannerService.scanUserExtensions({ language, useCache: true })
- .then(scannedExtensions => scannedExtensions.map(e => toExtensionDescription(e, false)));
-
- const developedExtensions = this._extensionsScannerService.scanExtensionsUnderDevelopment({ language })
- .then(scannedExtensions => scannedExtensions.map(e => toExtensionDescription(e, true)));
-
- return Promise.all([builtinExtensions, userExtensions, developedExtensions]).then((extensionDescriptions: IExtensionDescription[][]) => {
- const system = extensionDescriptions[0];
- const user = extensionDescriptions[1];
- const development = extensionDescriptions[2];
+ try {
+ const language = platform.language;
+ const [scannedSystemExtensions, scannedUserExtensions] = await Promise.all([
+ this._extensionsScannerService.scanSystemExtensions({ language, useCache: true, checkControlFile: true }),
+ this._extensionsScannerService.scanUserExtensions({ language, useCache: true })]);
+ const scannedDevelopedExtensions = await this._extensionsScannerService.scanExtensionsUnderDevelopment({ language }, [...scannedSystemExtensions, ...scannedUserExtensions]);
+ const system = scannedSystemExtensions.map(e => toExtensionDescription(e, false));
+ const user = scannedUserExtensions.map(e => toExtensionDescription(e, false));
+ const development = scannedDevelopedExtensions.map(e => toExtensionDescription(e, true));
const disposable = this._extensionsScannerService.onDidChangeCache(() => {
disposable.dispose();
this._notificationService.prompt(
@@ -78,11 +72,11 @@ export class CachedExtensionScanner {
});
timeout(5000).then(() => disposable.dispose());
return { system, user, development };
- }).then(undefined, err => {
+ } catch (err) {
this._logService.error(`Error scanning installed extensions:`);
this._logService.error(err);
return { system: [], user: [], development: [] };
- });
+ }
}
}