|
1 | 1 | import { getDefaultEnvManagerSetting, getDefaultPkgManagerSetting } from '../../features/settings/settingHelpers'; |
2 | 2 | import { EnvironmentManagers, PythonProjectManager } from '../../internal.api'; |
3 | 3 | import { getUvEnvironments } from '../../managers/builtin/uvEnvironments'; |
| 4 | +import { traceVerbose } from '../logging'; |
4 | 5 | import { getWorkspaceFolders } from '../workspace.apis'; |
5 | 6 | import { EventNames } from './constants'; |
6 | 7 | import { sendTelemetryEvent } from './sender'; |
@@ -106,43 +107,50 @@ export async function sendEnvironmentToolUsageTelemetry( |
106 | 107 | pm: PythonProjectManager, |
107 | 108 | envManagers: EnvironmentManagers, |
108 | 109 | ): Promise<void> { |
109 | | - const projects = pm.getProjects(); |
110 | | - |
111 | | - // Track which tools are used (Set ensures uniqueness) |
112 | | - const toolsUsed = new Set<string>(); |
| 110 | + try { |
| 111 | + const projects = pm.getProjects(); |
| 112 | + |
| 113 | + // Track which tools are used (Set ensures uniqueness) |
| 114 | + const toolsUsed = new Set<string>(); |
| 115 | + |
| 116 | + // Lazily loaded once when a venv environment is first encountered |
| 117 | + let uvEnvPaths: string[] | undefined; |
| 118 | + |
| 119 | + // Check which environment manager is used for each project |
| 120 | + for (const project of projects) { |
| 121 | + try { |
| 122 | + const env = await envManagers.getEnvironment(project.uri); |
| 123 | + if (env?.envId?.managerId) { |
| 124 | + let toolName = extractToolName(env.envId.managerId); |
| 125 | + |
| 126 | + // UV environments share the venv manager. Check the persistent UV env list instead |
| 127 | + if (toolName === 'venv' && env.environmentPath) { |
| 128 | + uvEnvPaths ??= await getUvEnvironments(); |
| 129 | + if (uvEnvPaths.includes(env.environmentPath.fsPath)) { |
| 130 | + toolName = 'uv'; |
| 131 | + } |
| 132 | + } |
113 | 133 |
|
114 | | - // Check which environment manager is used for each project |
115 | | - for (const project of projects) { |
116 | | - try { |
117 | | - const env = await envManagers.getEnvironment(project.uri); |
118 | | - if (env?.envId?.managerId) { |
119 | | - let toolName = extractToolName(env.envId.managerId); |
120 | | - |
121 | | - // UV environments share the venv manager. Check the persistent UV env list instead |
122 | | - if (toolName === 'venv' && env.environmentPath) { |
123 | | - // Lazily load UV environment paths only when a venv environment is encountered |
124 | | - const uvEnvPaths = await getUvEnvironments(); |
125 | | - if (uvEnvPaths.includes(env.environmentPath.fsPath)) { |
126 | | - toolName = 'uv'; |
| 134 | + // Normalize 'global' to 'system' for consistency |
| 135 | + if (toolName === 'global') { |
| 136 | + toolName = 'system'; |
127 | 137 | } |
128 | | - } |
129 | 138 |
|
130 | | - // Normalize 'global' to 'system' for consistency |
131 | | - if (toolName === 'global') { |
132 | | - toolName = 'system'; |
| 139 | + toolsUsed.add(toolName); |
133 | 140 | } |
134 | | - |
135 | | - toolsUsed.add(toolName); |
| 141 | + } catch { |
| 142 | + // Ignore errors when getting environment for a project |
136 | 143 | } |
137 | | - } catch { |
138 | | - // Ignore errors when getting environment for a project |
139 | 144 | } |
140 | | - } |
141 | 145 |
|
142 | | - // Fire one event per tool used |
143 | | - toolsUsed.forEach((tool) => { |
144 | | - sendTelemetryEvent(EventNames.ENVIRONMENT_TOOL_USAGE, undefined, { |
145 | | - toolName: tool, |
| 146 | + // Fire one event per tool used |
| 147 | + toolsUsed.forEach((tool) => { |
| 148 | + sendTelemetryEvent(EventNames.ENVIRONMENT_TOOL_USAGE, undefined, { |
| 149 | + toolName: tool, |
| 150 | + }); |
146 | 151 | }); |
147 | | - }); |
| 152 | + } catch (error) { |
| 153 | + // Telemetry failures must never disrupt extension activation |
| 154 | + traceVerbose('Failed to send environment tool usage telemetry:', error); |
| 155 | + } |
148 | 156 | } |
0 commit comments