mirror of
https://github.com/Microsoft/vscode
synced 2024-11-05 18:29:38 +00:00
- ignore empty content - be resilient while loading extensions
This commit is contained in:
parent
eb6f14df61
commit
cffee30671
3 changed files with 66 additions and 16 deletions
|
@ -224,7 +224,7 @@ export abstract class AbstractExtensionsProfileScannerService extends Disposable
|
|||
let storedProfileExtensions: IStoredProfileExtension[] | undefined;
|
||||
try {
|
||||
const content = await this.fileService.readFile(file);
|
||||
storedProfileExtensions = JSON.parse(content.value.toString());
|
||||
storedProfileExtensions = JSON.parse(content.value.toString().trim() || '[]');
|
||||
} catch (error) {
|
||||
if (toFileOperationResult(error) !== FileOperationResult.FILE_NOT_FOUND) {
|
||||
throw error;
|
||||
|
|
|
@ -403,6 +403,26 @@ suite('ExtensionsProfileScannerService', () => {
|
|||
} catch (error) { /*expected*/ }
|
||||
});
|
||||
|
||||
test('read extension when manifest is empty', async () => {
|
||||
const extensionsManifest = joinPath(extensionsLocation, 'extensions.json');
|
||||
await instantiationService.get(IFileService).writeFile(extensionsManifest, VSBuffer.fromString(''));
|
||||
|
||||
const testObject = instantiationService.createInstance(TestObject, extensionsLocation);
|
||||
const actual = await testObject.scanProfileExtensions(extensionsManifest);
|
||||
assert.deepStrictEqual(actual, []);
|
||||
});
|
||||
|
||||
test('read extension when manifest has empty lines and spaces', async () => {
|
||||
const extensionsManifest = joinPath(extensionsLocation, 'extensions.json');
|
||||
await instantiationService.get(IFileService).writeFile(extensionsManifest, VSBuffer.fromString(`
|
||||
|
||||
|
||||
`));
|
||||
const testObject = instantiationService.createInstance(TestObject, extensionsLocation);
|
||||
const actual = await testObject.scanProfileExtensions(extensionsManifest);
|
||||
assert.deepStrictEqual(actual, []);
|
||||
});
|
||||
|
||||
function aExtension(id: string, location: URI, e?: Partial<IExtension>): IExtension {
|
||||
return {
|
||||
identifier: { id },
|
||||
|
|
|
@ -8,7 +8,7 @@ import * as platform from 'vs/base/common/platform';
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { IExtensionDescription, ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
import { dedupExtensions } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { IExtensionsScannerService, toExtensionDescription } from 'vs/platform/extensionManagement/common/extensionsScannerService';
|
||||
import { IExtensionsScannerService, IScannedExtension, toExtensionDescription } from 'vs/platform/extensionManagement/common/extensionsScannerService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { localize } from 'vs/nls';
|
||||
|
@ -16,6 +16,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
|||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
||||
import { getErrorMessage } from 'vs/base/common/errors';
|
||||
|
||||
export class CachedExtensionScanner {
|
||||
|
||||
|
@ -53,26 +54,55 @@ export class CachedExtensionScanner {
|
|||
private async _scanInstalledExtensions(): Promise<IExtensionDescription[]> {
|
||||
try {
|
||||
const language = platform.language;
|
||||
const [scannedSystemExtensions, scannedUserExtensions] = await Promise.all([
|
||||
const result = await Promise.allSettled([
|
||||
this._extensionsScannerService.scanSystemExtensions({ language, useCache: true, checkControlFile: true }),
|
||||
this._extensionsScannerService.scanUserExtensions({ language, profileLocation: this._userDataProfileService.currentProfile.extensionsResource, useCache: true })]);
|
||||
const scannedDevelopedExtensions = await this._extensionsScannerService.scanExtensionsUnderDevelopment({ language }, [...scannedSystemExtensions, ...scannedUserExtensions]);
|
||||
|
||||
let scannedSystemExtensions: IScannedExtension[] = [],
|
||||
scannedUserExtensions: IScannedExtension[] = [],
|
||||
scannedDevelopedExtensions: IScannedExtension[] = [],
|
||||
hasErrors = false;
|
||||
|
||||
if (result[0].status === 'fulfilled') {
|
||||
scannedSystemExtensions = result[0].value;
|
||||
} else {
|
||||
hasErrors = true;
|
||||
this._logService.error(`Error scanning system extensions:`, getErrorMessage(result[0].reason));
|
||||
}
|
||||
|
||||
if (result[1].status === 'fulfilled') {
|
||||
scannedUserExtensions = result[1].value;
|
||||
} else {
|
||||
hasErrors = true;
|
||||
this._logService.error(`Error scanning user extensions:`, getErrorMessage(result[1].reason));
|
||||
}
|
||||
|
||||
try {
|
||||
scannedDevelopedExtensions = await this._extensionsScannerService.scanExtensionsUnderDevelopment({ language }, [...scannedSystemExtensions, ...scannedUserExtensions]);
|
||||
} catch (error) {
|
||||
this._logService.error(error);
|
||||
}
|
||||
|
||||
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 r = dedupExtensions(system, user, development, this._logService);
|
||||
const disposable = this._extensionsScannerService.onDidChangeCache(() => {
|
||||
disposable.dispose();
|
||||
this._notificationService.prompt(
|
||||
Severity.Error,
|
||||
localize('extensionCache.invalid', "Extensions have been modified on disk. Please reload the window."),
|
||||
[{
|
||||
label: localize('reloadWindow', "Reload Window"),
|
||||
run: () => this._hostService.reload()
|
||||
}]
|
||||
);
|
||||
});
|
||||
timeout(5000).then(() => disposable.dispose());
|
||||
|
||||
if (!hasErrors) {
|
||||
const disposable = this._extensionsScannerService.onDidChangeCache(() => {
|
||||
disposable.dispose();
|
||||
this._notificationService.prompt(
|
||||
Severity.Error,
|
||||
localize('extensionCache.invalid', "Extensions have been modified on disk. Please reload the window."),
|
||||
[{
|
||||
label: localize('reloadWindow', "Reload Window"),
|
||||
run: () => this._hostService.reload()
|
||||
}]
|
||||
);
|
||||
});
|
||||
timeout(5000).then(() => disposable.dispose());
|
||||
}
|
||||
|
||||
return r;
|
||||
} catch (err) {
|
||||
this._logService.error(`Error scanning installed extensions:`);
|
||||
|
|
Loading…
Reference in a new issue