Skip to content

Commit 0ce8832

Browse files
authored
Merge pull request dotnet#2334 from dotnet/copilot/fix-2297
Hide verbose error details for user-friendly installer exit codes
2 parents 4a6b450 + 2f47412 commit 0ce8832

File tree

9 files changed

+3066
-3683
lines changed

9 files changed

+3066
-3683
lines changed

sample/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sample/yarn.lock

Lines changed: 2269 additions & 3062 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vscode-dotnet-runtime-extension/yarn.lock

Lines changed: 269 additions & 90 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vscode-dotnet-runtime-library/src/Acquisition/DotnetCoreAcquisitionWorker.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ import
3535
DotnetWSLSecurityError,
3636
EventBasedError,
3737
EventCancellationError,
38-
SuppressedAcquisitionError,
39-
UtilizingExistingInstallPromise
38+
SuppressedAcquisitionError
4039
} from '../EventStream/EventStreamEvents';
4140
import * as versionUtils from './VersionUtilities';
4241

@@ -396,15 +395,19 @@ To keep your .NET version up to date, please reconnect to the internet at your s
396395
{
397396
if (error instanceof EventBasedError || error instanceof EventCancellationError)
398397
{
399-
error.message = `.NET Acquisition Failed: ${error.message}, ${error?.stack}`;
400398
return error;
401399
}
402400
else
403401
{
404-
// Remove this when https://github.com/typescript-eslint/typescript-eslint/issues/2728 is done
405402
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
406-
const newError = new EventBasedError('DotnetAcquisitionError', `.NET Acquisition Failed: ${error?.message ?? JSON.stringify(error)}`);
407-
return newError;
403+
if (error?.error?.message !== undefined) // DotnetAcquisitionError is a bad but common pattern where the error is included in the thrown object
404+
{
405+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
406+
return new EventBasedError(error?.constructor?.name ?? 'DotnetAcquisitionError', error?.error?.message, error?.stack);
407+
}
408+
409+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
410+
return new EventBasedError('DotnetAcquisitionError', `.NET Acquisition Failed: ${error?.message ?? JSON.stringify(error)}`);
408411
}
409412
}
410413

@@ -452,9 +455,15 @@ To keep your .NET version up to date, please reconnect to the internet at your s
452455

453456
if (installerResult !== '0')
454457
{
458+
// For user-friendly exit codes, show only the interpreted message without verbose details
459+
const interpretedMessage = WinMacGlobalInstaller.InterpretExitCode(installerResult);
460+
const errorMessage = WinMacGlobalInstaller.IsUserFriendlyExitCode(installerResult)
461+
? interpretedMessage
462+
: `An error was raised by the .NET SDK installer. The exit code it gave us: ${installerResult}.
463+
${interpretedMessage}`;
464+
455465
const err = new DotnetNonZeroInstallerExitCodeError(new EventBasedError('DotnetNonZeroInstallerExitCodeError',
456-
`An error was raised by the .NET SDK installer. The exit code it gave us: ${installerResult}.
457-
${WinMacGlobalInstaller.InterpretExitCode(installerResult)}`), install);
466+
errorMessage), install);
458467
context.eventStream.post(err);
459468
throw err;
460469
}

vscode-dotnet-runtime-library/src/Acquisition/WinMacGlobalInstaller.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ We cannot verify our .NET file host at this time. Please try again later or inst
8585
this.registry = registryReader ?? new RegistryReader(context, utilContext);
8686
}
8787

88+
/**
89+
* Determines if the given exit code has a user-friendly, self-contained error message
90+
* that doesn't need additional technical details to be helpful to the user.
91+
*/
92+
public static IsUserFriendlyExitCode(code: string): boolean
93+
{
94+
return this.InterpretExitCode(code) !== '';
95+
}
96+
8897
public static InterpretExitCode(code: string): string
8998
{
9099
const reportLogMessage = `Please provide your .NET Installer log (note our privacy notice), which can be found at %temp%.
@@ -98,23 +107,23 @@ This report should be made at https://github.com/dotnet/vscode-dotnet-runtime/is
98107
case '5':
99108
return `Insufficient permissions are available to install .NET. Please run the installer as an administrator.`;
100109
case '67':
101-
return `The network name cannot be found. ${reportLogMessage}`;
110+
return `The network name cannot be found to install .NET. ${reportLogMessage}`;
102111
case '112':
103112
return `The disk is full. Please free up space and try again.`;
104113
case '255':
105114
return `The .NET Installer was terminated by another process unexpectedly. Please try again.`;
106115
case '1260':
107-
return `The .NET SDK is blocked by group policy. Can you please report this at https://github.com/dotnet/vscode-dotnet-runtime/issues`
116+
return `The .NET SDK Install is blocked by group policy. For more information, contact your system administrator.`
108117
case '1460':
109118
return `The .NET SDK had a timeout error. ${reportLogMessage}`;
110119
case '1603':
111120
return `Fatal error during .NET SDK installation. ${reportLogMessage}`;
112121
case '1618':
113122
return `Another installation is already in progress. Complete that installation before proceeding with this install.`;
114123
case '000751':
115-
return `Page fault was satisfied by reading from a secondary storage device. ${reportLogMessage}`;
124+
return `.NET Installer Failed: A page fault was satisfied by reading from a secondary storage device. ${reportLogMessage}`;
116125
case '2147500037':
117-
return `An unspecified error occurred. ${reportLogMessage}`;
126+
return `.NET Installer Failed: An unspecified error occurred. ${reportLogMessage}`;
118127
case '2147942405':
119128
return `Insufficient permissions are available to install .NET. Please try again as an administrator.`;
120129
case UNABLE_TO_ACQUIRE_GLOBAL_LOCK_ERR:

vscode-dotnet-runtime-library/src/EventStream/OutputChannelObserver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import
1515
DotnetOfflineInstallUsed,
1616
DotnetOfflineWarning,
1717
DotnetUpgradedEvent,
18-
DotnetVisibleWarningEvent,
18+
DotnetVisibleWarningEvent
1919
} from './EventStreamEvents';
2020
import { EventType } from './EventType';
2121
import { IEvent } from './IEvent';

vscode-dotnet-runtime-library/src/test/unit/WinMacGlobalInstaller.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,22 @@ ${fs.readdirSync(installerDownloadFolder).join(', ')}`);
225225
}
226226
}
227227
}).timeout(standardTimeoutTime);
228+
229+
test('InterpretExitCode returns user-friendly messages for common exit codes', () =>
230+
{
231+
// Test exit code 5 - insufficient permissions
232+
const exitCode5Message = WinMacGlobalInstaller.InterpretExitCode('5');
233+
assert.equal(exitCode5Message, 'Insufficient permissions are available to install .NET. Please run the installer as an administrator.');
234+
assert.isFalse(exitCode5Message.includes('report'), 'Exit code 5 should not ask for bug reports');
235+
assert.isTrue(WinMacGlobalInstaller.IsUserFriendlyExitCode('5'), 'Exit code 5 should be marked as user-friendly');
236+
237+
// Test exit code 1 - generic failure (should include report message)
238+
const exitCode1Message = WinMacGlobalInstaller.InterpretExitCode('1');
239+
assert.isTrue(exitCode1Message.includes('report'), 'Exit code 1 should ask for bug reports');
240+
241+
// Test unknown exit code
242+
const unknownCodeMessage = WinMacGlobalInstaller.InterpretExitCode('9999');
243+
assert.equal(unknownCodeMessage, '', 'Unknown exit codes should return empty string');
244+
assert.isFalse(WinMacGlobalInstaller.IsUserFriendlyExitCode('9999'), 'Unknown exit codes should not be marked as user-friendly');
245+
});
228246
});

vscode-dotnet-runtime-library/yarn.lock

Lines changed: 24 additions & 63 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)