-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
vscode-python/src/client/extension.ts
Lines 54 to 72 in 893b44f
| export async function activate(context: IExtensionContext): Promise<IExtensionApi> { | |
| let api: IExtensionApi; | |
| let ready: Promise<void>; | |
| let serviceContainer: IServiceContainer; | |
| try { | |
| [api, ready, serviceContainer] = await activateUnsafe(context, stopWatch, durations); | |
| } catch (ex) { | |
| // We want to completely handle the error | |
| // before notifying VS Code. | |
| await handleError(ex, durations); | |
| throw ex; // re-raise | |
| } | |
| // Send the "success" telemetry only if activation did not fail. | |
| // Otherwise Telemetry is send via the error handler. | |
| sendStartupTelemetry(ready, durations, stopWatch, serviceContainer) | |
| // Run in the background. | |
| .ignoreErrors(); | |
| return api; | |
| } |
Note that this code does not await ready. It does await the return value of activateUnsafe(), but that's not the same thing.
The effect is that when activate() returns, our command handlers might not actually be registered yet, and so if something tries to invoke them, it fails. One particular case where this can be consistently observed is our interaction with the Docker extension - in its debug configuration resolver, if the config is for Python, it uses VSCode API to activate vscode-python, and then assumes that it can return ${command:python.interpreterPath} in the config and have it properly expanded. But, because of the race condition, it often ends up as a blank string.
I believe the same is potentially possible with any command that we register under "activationEvents" in our manifest, since VSCode does essentially the same - activate(), then try to locate the command handler and execute it. This might be the root cause of #12072 and similar.