From f417024a1f4671c19f0959128a063c7b2fe98198 Mon Sep 17 00:00:00 2001 From: Anthony Kim <62267334+anthonykim1@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:05:59 -0700 Subject: [PATCH] Attempt to handle pixi error more gracefully (#23937) For: https://github.com/microsoft/vscode-python/issues/23911 and https://github.com/microsoft/vscode-python/issues/23906 (For virtual/remote scenario) Locating pixi environment, regardless of presence of pixi environment, is leading to crash. Hoping to address this and handle errors more gracefully so program does not terminate. /cc @baszalmstra --- .../common/environmentManagers/pixi.ts | 67 +++++++++++++------ 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/src/client/pythonEnvironments/common/environmentManagers/pixi.ts b/src/client/pythonEnvironments/common/environmentManagers/pixi.ts index f3d6dc3e081e..7aa1d55acd2c 100644 --- a/src/client/pythonEnvironments/common/environmentManagers/pixi.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/pixi.ts @@ -169,16 +169,22 @@ export class Pixi { */ @cache(1_000, true, 1_000) public async getPixiInfo(cwd: string): Promise { - const infoOutput = await exec(this.command, ['info', '--json'], { - cwd, - throwOnStdErr: false, - }).catch(traceError); - if (!infoOutput) { + try { + const infoOutput = await exec(this.command, ['info', '--json'], { + cwd, + throwOnStdErr: false, + }); + + if (!infoOutput || !infoOutput.stdout) { + return undefined; + } + + const pixiInfo: PixiInfo = JSON.parse(infoOutput.stdout); + return pixiInfo; + } catch (error) { + traceError(`Failed to get pixi info for ${cwd}`, error); return undefined; } - - const pixiInfo: PixiInfo = JSON.parse(infoOutput.stdout); - return pixiInfo; } /** @@ -186,14 +192,24 @@ export class Pixi { */ @cache(30_000, true, 10_000) public async getVersion(): Promise { - const versionOutput = await exec(this.command, ['--version'], { - throwOnStdErr: false, - }).catch(traceError); - if (!versionOutput) { + try { + const versionOutput = await exec(this.command, ['--version'], { + throwOnStdErr: false, + }); + if (!versionOutput || !versionOutput.stdout) { + return undefined; + } + + const versionParts = versionOutput.stdout.split(' '); + if (versionParts.length < 2) { + return undefined; + } + + return versionParts[1].trim(); + } catch (error) { + traceError(`Failed to get pixi version`, error); return undefined; } - - return versionOutput.stdout.split(' ')[1].trim(); } /** @@ -279,13 +295,24 @@ export async function getPixiEnvironmentFromInterpreter( // Usually the pixi environments are stored under `/.pixi/envs//`. So, // we walk backwards to determine the project directory. - const envName = path.basename(prefix); - const envsDir = path.dirname(prefix); - const dotPixiDir = path.dirname(envsDir); - const pixiProjectDir = path.dirname(dotPixiDir); + let envName: string | undefined; + let envsDir: string; + let dotPixiDir: string; + let pixiProjectDir: string; + let pixiInfo: PixiInfo | undefined; + + try { + envName = path.basename(prefix); + envsDir = path.dirname(prefix); + dotPixiDir = path.dirname(envsDir); + pixiProjectDir = path.dirname(dotPixiDir); + + // Invoke pixi to get information about the pixi project + pixiInfo = await pixi.getPixiInfo(pixiProjectDir); + } catch (error) { + traceWarn('Error processing paths or getting Pixi Info:', error); + } - // Invoke pixi to get information about the pixi project - const pixiInfo = await pixi.getPixiInfo(pixiProjectDir); if (!pixiInfo || !pixiInfo.project_info) { traceWarn(`failed to determine pixi project information for the interpreter at ${interpreterPath}`); return undefined;