Skip to content

Commit 5f88d8c

Browse files
committed
Improve error details when dotnet --info fails
1 parent 061fc6d commit 5f88d8c

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

src/shared/utils/getDotnetInfo.ts

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,55 @@ import { join } from 'path';
88
import { execChildProcess } from '../../common';
99
import { CoreClrDebugUtil } from '../../coreclrDebug/util';
1010
import { DotnetInfo } from './dotnetInfo';
11+
import { EOL } from 'os';
1112

1213
// This function calls `dotnet --info` and returns the result as a DotnetInfo object.
1314
export async function getDotnetInfo(dotNetCliPaths: string[]): Promise<DotnetInfo> {
1415
const dotnetExecutablePath = getDotNetExecutablePath(dotNetCliPaths);
1516

17+
const data = await runDotnetInfo(dotnetExecutablePath);
18+
const dotnetInfo = await parseDotnetInfo(data, dotnetExecutablePath);
19+
return dotnetInfo;
20+
}
21+
22+
export function getDotNetExecutablePath(dotNetCliPaths: string[]): string | undefined {
23+
const dotnetExeName = `dotnet${CoreClrDebugUtil.getPlatformExeExtension()}`;
24+
let dotnetExecutablePath: string | undefined;
25+
26+
for (const dotnetPath of dotNetCliPaths) {
27+
const dotnetFullPath = join(dotnetPath, dotnetExeName);
28+
if (CoreClrDebugUtil.existsSync(dotnetFullPath)) {
29+
dotnetExecutablePath = dotnetFullPath;
30+
break;
31+
}
32+
}
33+
return dotnetExecutablePath;
34+
}
35+
36+
async function runDotnetInfo(dotnetExecutablePath: string | undefined): Promise<string> {
1637
try {
1738
const env = {
1839
...process.env,
1940
DOTNET_CLI_UI_LANGUAGE: 'en-US',
2041
};
2142
const data = await execChildProcess(`${dotnetExecutablePath ?? 'dotnet'} --info`, process.cwd(), env);
43+
return data;
44+
} catch (error) {
45+
const message = error instanceof Error ? error.message : `${error}`;
46+
throw new Error(`Error running dotnet --info: ${message}`);
47+
}
48+
}
2249

50+
async function parseDotnetInfo(dotnetInfo: string, dotnetExecutablePath: string | undefined): Promise<DotnetInfo> {
51+
try {
2352
const cliPath = dotnetExecutablePath;
24-
const fullInfo = data;
53+
const fullInfo = dotnetInfo;
2554

2655
let version: string | undefined;
2756
let runtimeId: string | undefined;
2857
let architecture: string | undefined;
2958

30-
let lines = data.replace(/\r/gm, '').split('\n');
59+
let lines = dotnetInfo.replace(/\r/gm, '').split('\n');
3160
for (const line of lines) {
3261
let match: RegExpMatchArray | null;
3362
if ((match = /^\s*Version:\s*([^\s].*)$/.exec(line))) {
@@ -68,22 +97,8 @@ export async function getDotnetInfo(dotNetCliPaths: string[]): Promise<DotnetInf
6897
}
6998

7099
throw new Error('Failed to parse dotnet version information');
71-
} catch {
72-
// something went wrong with spawning 'dotnet --info'
73-
throw new Error('A valid dotnet installation could not be found');
74-
}
75-
}
76-
77-
export function getDotNetExecutablePath(dotNetCliPaths: string[]): string | undefined {
78-
const dotnetExeName = `dotnet${CoreClrDebugUtil.getPlatformExeExtension()}`;
79-
let dotnetExecutablePath: string | undefined;
80-
81-
for (const dotnetPath of dotNetCliPaths) {
82-
const dotnetFullPath = join(dotnetPath, dotnetExeName);
83-
if (CoreClrDebugUtil.existsSync(dotnetFullPath)) {
84-
dotnetExecutablePath = dotnetFullPath;
85-
break;
86-
}
100+
} catch (error) {
101+
const message = error instanceof Error ? error.message : `${error}`;
102+
throw new Error(`Error parsing dotnet --info: ${message}, raw info was:${EOL}${dotnetInfo}`);
87103
}
88-
return dotnetExecutablePath;
89104
}

0 commit comments

Comments
 (0)