Skip to content

Commit 0d4fcfc

Browse files
author
Liangcheng Juves
committed
Merge branch 'microsoft:main' into main
2 parents a88cd35 + 27b2434 commit 0d4fcfc

File tree

6 files changed

+55
-36
lines changed

6 files changed

+55
-36
lines changed

src/vs/code/electron-main/app.ts

+14-5
Original file line numberDiff line numberDiff line change
@@ -898,29 +898,38 @@ export class CodeApplication extends Disposable {
898898

899899
// Logging
900900
let message: string;
901-
if (typeof details === 'string') {
902-
message = details;
903-
} else {
904-
message = `SharedProcess: crashed (detail: ${details.reason}, code: ${details.exitCode})`;
901+
switch (type) {
902+
case WindowError.UNRESPONSIVE:
903+
message = 'SharedProcess: detected unresponsive window';
904+
break;
905+
case WindowError.CRASHED:
906+
message = `SharedProcess: crashed (detail: ${details?.reason ?? '<unknown>'}, code: ${details?.exitCode ?? '<unknown>'})`;
907+
break;
908+
case WindowError.LOAD:
909+
message = `SharedProcess: failed to load (detail: ${details?.reason ?? '<unknown>'}, code: ${details?.exitCode ?? '<unknown>'})`;
910+
break;
905911
}
906912
onUnexpectedError(new Error(message));
907913

908914
// Telemetry
909915
type SharedProcessErrorClassification = {
910916
type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
911917
reason: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
918+
code: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
912919
visible: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
913920
shuttingdown: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
914921
};
915922
type SharedProcessErrorEvent = {
916923
type: WindowError;
917924
reason: string | undefined;
925+
code: number | undefined;
918926
visible: boolean;
919927
shuttingdown: boolean;
920928
};
921929
telemetryService.publicLog2<SharedProcessErrorEvent, SharedProcessErrorClassification>('sharedprocesserror', {
922930
type,
923-
reason: typeof details !== 'string' ? details?.reason : undefined,
931+
reason: details?.reason,
932+
code: details?.exitCode,
924933
visible: sharedProcess.isVisible(),
925934
shuttingdown: willShutdown
926935
});

src/vs/platform/sharedProcess/electron-main/sharedProcess.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import product from 'vs/platform/product/common/product';
7-
import { BrowserWindow, ipcMain, Event as ElectronEvent, MessagePortMain, IpcMainEvent, RenderProcessGoneDetails } from 'electron';
7+
import { BrowserWindow, ipcMain, Event as ElectronEvent, MessagePortMain, IpcMainEvent } from 'electron';
88
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
99
import { Barrier } from 'vs/base/common/async';
1010
import { ILogService } from 'vs/platform/log/common/log';
@@ -27,7 +27,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
2727
private window: BrowserWindow | undefined = undefined;
2828
private windowCloseListener: ((event: ElectronEvent) => void) | undefined = undefined;
2929

30-
private readonly _onDidError = this._register(new Emitter<{ type: WindowError, details: string | RenderProcessGoneDetails }>());
30+
private readonly _onDidError = this._register(new Emitter<{ type: WindowError, details?: { reason: string, exitCode: number } }>());
3131
readonly onDidError = Event.buffer(this._onDidError.event); // buffer until we have a listener!
3232

3333
constructor(
@@ -219,8 +219,8 @@ export class SharedProcess extends Disposable implements ISharedProcess {
219219
// We use `onUnexpectedError` explicitly because the error handler
220220
// will send the error to the active window to log in devtools too
221221
this.window.webContents.on('render-process-gone', (event, details) => this._onDidError.fire({ type: WindowError.CRASHED, details }));
222-
this.window.on('unresponsive', () => this._onDidError.fire({ type: WindowError.UNRESPONSIVE, details: 'SharedProcess: detected unresponsive window' }));
223-
this.window.webContents.on('did-fail-load', (event, errorCode, errorDescription) => this._onDidError.fire({ type: WindowError.LOAD, details: `SharedProcess: failed to load: ${errorDescription}` }));
222+
this.window.on('unresponsive', () => this._onDidError.fire({ type: WindowError.UNRESPONSIVE }));
223+
this.window.webContents.on('did-fail-load', (event, exitCode, reason) => this._onDidError.fire({ type: WindowError.LOAD, details: { reason, exitCode } }));
224224
}
225225

226226
async connect(): Promise<MessagePortMain> {

src/vs/platform/terminal/node/terminalProfiles.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function detectAvailableProfiles(
2626
fsProvider?: IFsProvider,
2727
logService?: ILogService,
2828
variableResolver?: (text: string[]) => Promise<string[]>,
29-
testPaths?: string[]
29+
testPwshSourcePaths?: string[]
3030
): Promise<ITerminalProfile[]> {
3131
fsProvider = fsProvider || {
3232
existsFile: pfs.SymlinkSupport.existsFile,
@@ -40,7 +40,7 @@ export function detectAvailableProfiles(
4040
configurationService.getValue<boolean>(TerminalSettingId.UseWslProfiles) !== false,
4141
profiles && typeof profiles === 'object' ? { ...profiles } : configurationService.getValue<{ [key: string]: ITerminalProfileObject }>(TerminalSettingId.ProfilesWindows),
4242
typeof defaultProfile === 'string' ? defaultProfile : configurationService.getValue<string>(TerminalSettingId.DefaultProfileWindows),
43-
testPaths,
43+
testPwshSourcePaths,
4444
variableResolver
4545
);
4646
}
@@ -50,7 +50,7 @@ export function detectAvailableProfiles(
5050
includeDetectedProfiles,
5151
profiles && typeof profiles === 'object' ? { ...profiles } : configurationService.getValue<{ [key: string]: ITerminalProfileObject }>(isLinux ? TerminalSettingId.ProfilesLinux : TerminalSettingId.ProfilesMacOs),
5252
typeof defaultProfile === 'string' ? defaultProfile : configurationService.getValue<string>(isLinux ? TerminalSettingId.DefaultProfileLinux : TerminalSettingId.DefaultProfileMacOs),
53-
testPaths,
53+
testPwshSourcePaths,
5454
variableResolver
5555
);
5656
}
@@ -62,7 +62,7 @@ async function detectAvailableWindowsProfiles(
6262
useWslProfiles?: boolean,
6363
configProfiles?: { [key: string]: ITerminalProfileObject },
6464
defaultProfileName?: string,
65-
testPaths?: string[],
65+
testPwshSourcePaths?: string[],
6666
variableResolver?: (text: string[]) => Promise<string[]>
6767
): Promise<ITerminalProfile[]> {
6868
// Determine the correct System32 path. We want to point to Sysnative
@@ -78,7 +78,7 @@ async function detectAvailableWindowsProfiles(
7878
useWSLexe = true;
7979
}
8080

81-
await initializeWindowsProfiles(testPaths);
81+
await initializeWindowsProfiles(testPwshSourcePaths);
8282

8383
const detectedProfiles: Map<string, ITerminalProfileObject> = new Map();
8484

@@ -180,8 +180,8 @@ async function transformToTerminalProfiles(
180180
return resultProfiles;
181181
}
182182

183-
async function initializeWindowsProfiles(testPaths?: string[]): Promise<void> {
184-
if (profileSources) {
183+
async function initializeWindowsProfiles(testPwshSourcePaths?: string[]): Promise<void> {
184+
if (profileSources && !testPwshSourcePaths) {
185185
return;
186186
}
187187

@@ -202,7 +202,7 @@ async function initializeWindowsProfiles(testPaths?: string[]): Promise<void> {
202202
});
203203
profileSources.set('PowerShell', {
204204
profileName: 'PowerShell',
205-
paths: testPaths || await getPowershellPaths(),
205+
paths: testPwshSourcePaths || await getPowershellPaths(),
206206
icon: ThemeIcon.asThemeIcon(Codicon.terminalPowershell)
207207
});
208208
}

src/vs/platform/windows/electron-main/window.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
88
import { getMarks, mark } from 'vs/base/common/performance';
99
import { Emitter } from 'vs/base/common/event';
1010
import { URI } from 'vs/base/common/uri';
11-
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, Event, RenderProcessGoneDetails, WebFrameMain } from 'electron';
11+
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, Event, WebFrameMain } from 'electron';
1212
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
1313
import { ILogService } from 'vs/platform/log/common/log';
1414
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -419,7 +419,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
419419
// Crashes & Unresponsive & Failed to load
420420
this._win.on('unresponsive', () => this.onWindowError(WindowError.UNRESPONSIVE));
421421
this._win.webContents.on('render-process-gone', (event, details) => this.onWindowError(WindowError.CRASHED, details));
422-
this._win.webContents.on('did-fail-load', (event, errorCode, errorDescription) => this.onWindowError(WindowError.LOAD, errorDescription));
422+
this._win.webContents.on('did-fail-load', (event, exitCode, reason) => this.onWindowError(WindowError.LOAD, { reason, exitCode }));
423423

424424
// Prevent windows/iframes from blocking the unload
425425
// through DOM events. We have our own logic for
@@ -551,19 +551,19 @@ export class CodeWindow extends Disposable implements ICodeWindow {
551551
}
552552

553553
private async onWindowError(error: WindowError.UNRESPONSIVE): Promise<void>;
554-
private async onWindowError(error: WindowError.CRASHED, details: RenderProcessGoneDetails): Promise<void>;
555-
private async onWindowError(error: WindowError.LOAD, details: string): Promise<void>;
556-
private async onWindowError(type: WindowError, details?: string | RenderProcessGoneDetails): Promise<void> {
554+
private async onWindowError(error: WindowError.CRASHED, details: { reason: string, exitCode: number }): Promise<void>;
555+
private async onWindowError(error: WindowError.LOAD, details: { reason: string, exitCode: number }): Promise<void>;
556+
private async onWindowError(type: WindowError, details?: { reason: string, exitCode: number }): Promise<void> {
557557

558558
switch (type) {
559559
case WindowError.CRASHED:
560-
this.logService.error(`CodeWindow: renderer process crashed (detail: ${typeof details === 'string' ? details : details?.reason}, code: ${typeof details === 'string' ? '<unknown>' : details?.exitCode ?? '<unknown>'})`);
560+
this.logService.error(`CodeWindow: renderer process crashed (reason: ${details?.reason ?? '<unknown>'}, code: ${details?.exitCode ?? '<unknown>'})`);
561561
break;
562562
case WindowError.UNRESPONSIVE:
563563
this.logService.error('CodeWindow: detected unresponsive');
564564
break;
565565
case WindowError.LOAD:
566-
this.logService.error(`CodeWindow: failed to load workbench window: ${typeof details === 'string' ? details : details?.reason}`);
566+
this.logService.error(`CodeWindow: failed to load workbench window (reason: ${details?.reason ?? '<unknown>'}, code: ${details?.exitCode ?? '<unknown>'})`);
567567
break;
568568
}
569569

@@ -579,12 +579,14 @@ export class CodeWindow extends Disposable implements ICodeWindow {
579579
type WindowErrorClassification = {
580580
type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
581581
reason: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
582+
code: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
582583
};
583584
type WindowErrorEvent = {
584585
type: WindowError;
585586
reason: string | undefined;
587+
code: number | undefined;
586588
};
587-
this.telemetryService.publicLog2<WindowErrorEvent, WindowErrorClassification>('windowerror', { type, reason: typeof details !== 'string' ? details?.reason : undefined });
589+
this.telemetryService.publicLog2<WindowErrorEvent, WindowErrorClassification>('windowerror', { type, reason: details?.reason, code: details?.exitCode });
588590

589591
// Unresponsive
590592
if (type === WindowError.UNRESPONSIVE) {
@@ -623,10 +625,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
623625
// Crashed
624626
else if (type === WindowError.CRASHED) {
625627
let message: string;
626-
if (typeof details === 'string' || !details) {
628+
if (!details) {
627629
message = localize('appCrashed', "The window has crashed");
628630
} else {
629-
message = localize('appCrashedDetails', "The window has crashed (reason: '{0}')", details.reason);
631+
message = localize('appCrashedDetails', "The window has crashed (reason: '{0}', code: '{1}')", details.reason, details.exitCode ?? '<unknown>');
630632
}
631633

632634
const result = await this.dialogMainService.showMessageBox({

src/vs/workbench/browser/web.main.ts

+4
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,16 @@ class BrowserMain extends Disposable {
313313
async run(accessor: ServicesAccessor): Promise<void> {
314314
const dialogService = accessor.get(IDialogService);
315315
const hostService = accessor.get(IHostService);
316+
const storageService = accessor.get(IStorageService);
316317
const result = await dialogService.confirm({
317318
message: localize('reset user data message', "Would you like to reset your data (settings, keybindings, extensions, snippets and UI State) and reload?")
318319
});
319320

320321
if (result.confirmed) {
321322
await indexedDBUserDataProvider?.reset();
323+
if (storageService instanceof BrowserStorageService) {
324+
await storageService.clear();
325+
}
322326
}
323327

324328
hostService.reload();

src/vs/workbench/contrib/terminal/test/node/terminalProfiles.test.ts

+13-9
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ suite('Workbench - TerminalProfiles', () => {
5252
profilesEqual(profiles, expected);
5353
});
5454
test('should allow source to have args', async () => {
55-
const fsProvider = createFsProvider([
55+
const pwshSourcePaths = [
5656
'C:\\Program Files\\PowerShell\\7\\pwsh.exe'
57-
]);
57+
];
58+
const fsProvider = createFsProvider(pwshSourcePaths);
5859
const config: ITestTerminalConfig = {
5960
profiles: {
6061
windows: {
@@ -66,7 +67,7 @@ suite('Workbench - TerminalProfiles', () => {
6667
useWslProfiles: false
6768
};
6869
const configurationService = new TestConfigurationService({ terminal: { integrated: config } });
69-
const profiles = await detectAvailableProfiles(undefined, undefined, false, configurationService, fsProvider, undefined, undefined, undefined);
70+
const profiles = await detectAvailableProfiles(undefined, undefined, false, configurationService, fsProvider, undefined, undefined, pwshSourcePaths);
7071
const expected = [
7172
{ profileName: 'PowerShell', path: 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', overrideName: true, args: ['-NoProfile'], isDefault: true }
7273
];
@@ -104,39 +105,42 @@ suite('Workbench - TerminalProfiles', () => {
104105
} as ITestTerminalConfig) as ITerminalConfiguration;
105106

106107
test('should prefer pwsh 7 to Windows PowerShell', async () => {
107-
const expectedPaths = [
108+
const pwshSourcePaths = [
108109
'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
109110
'C:\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe',
110111
'C:\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
111112
];
113+
const fsProvider = createFsProvider(pwshSourcePaths);
112114
const configurationService = new TestConfigurationService({ terminal: { integrated: pwshSourceConfig } });
113-
const profiles = await detectAvailableProfiles(undefined, undefined, false, configurationService, undefined, undefined, undefined, expectedPaths);
115+
const profiles = await detectAvailableProfiles(undefined, undefined, false, configurationService, fsProvider, undefined, undefined, pwshSourcePaths);
114116
const expected = [
115117
{ profileName: 'PowerShell', path: 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', isDefault: true }
116118
];
117119
profilesEqual(profiles, expected);
118120
});
119121
test('should prefer pwsh 7 to pwsh 6', async () => {
120-
const expectedPaths = [
122+
const pwshSourcePaths = [
121123
'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
122124
'C:\\Program Files\\PowerShell\\6\\pwsh.exe',
123125
'C:\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe',
124126
'C:\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
125127
];
128+
const fsProvider = createFsProvider(pwshSourcePaths);
126129
const configurationService = new TestConfigurationService({ terminal: { integrated: pwshSourceConfig } });
127-
const profiles = await detectAvailableProfiles(undefined, undefined, false, configurationService, undefined, undefined, undefined, expectedPaths);
130+
const profiles = await detectAvailableProfiles(undefined, undefined, false, configurationService, fsProvider, undefined, undefined, pwshSourcePaths);
128131
const expected = [
129132
{ profileName: 'PowerShell', path: 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', isDefault: true }
130133
];
131134
profilesEqual(profiles, expected);
132135
});
133136
test('should fallback to Windows PowerShell', async () => {
134-
const expectedPaths = [
137+
const pwshSourcePaths = [
135138
'C:\\Windows\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe',
136139
'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
137140
];
141+
const fsProvider = createFsProvider(pwshSourcePaths);
138142
const configurationService = new TestConfigurationService({ terminal: { integrated: pwshSourceConfig } });
139-
const profiles = await detectAvailableProfiles(undefined, undefined, false, configurationService, undefined, undefined, undefined, expectedPaths);
143+
const profiles = await detectAvailableProfiles(undefined, undefined, false, configurationService, fsProvider, undefined, undefined, pwshSourcePaths);
140144
strictEqual(profiles.length, 1);
141145
strictEqual(profiles[0].profileName, 'PowerShell');
142146
});

0 commit comments

Comments
 (0)