feat(python-setup): add "Install uv" button to the uv-missing error - #2113
Merged
Conversation
*Why*
When `environments setup-local` fails because uv is not installed
(`E_UV_MISSING`), the error popup only offered "Show Logs", leaving the
user to find and install uv on their own. Give them a one-click path to
uv's install guide, matching how the extension already surfaces the
Azure CLI install instructions.
*What*
- errorMessages.ts: single-source `UV_INSTALL_DOCS_URL` and a small
`getPythonSetupErrorAction(result)` helper that returns an
{label, url} action only for `E_UV_MISSING`, so the call-to-action
lives next to the message copy.
- PythonSetupEnvironmentSetup.ts: `showError` gains an optional `action`
arg; the failure path passes `getPythonSetupErrorAction(result)`.
- pythonSetupDeps.ts: render the remediation button first (before
"Show Logs") and open its URL via the existing `openExternal` helper
when picked. Deliberately links to the docs (which pick the right
installer per platform) rather than running an installer itself.
The `action` param is optional, so the other `showError` call sites are
unchanged and keep their Show-Logs-only popup.
*Verification*
- TDD: 5 new unit tests (errorMessages action mapping; deps button shown
+ URL opened on pick, not opened otherwise; orchestrator passes the
action on uv-missing and none on other failures).
- yarn test:unit — 739 passing, 0 failing.
- tsc --noEmit clean; yarn test:lint + Prettier clean.
Co-authored-by: Isaac
Contributor
Author
|
🤖 Integration tests ❌ 3 of 4 test jobs failed for |
…s label *Why* Code review (Isaac + Codex + Claude) independently flagged that `showErrorMessage` returns the picked button as a bare label string, so two buttons sharing a label are indistinguishable. If a future `PythonSetupErrorAction` ever used the reserved "Show Logs" label, its URL branch would be dead code and the click would show the log instead. Harmless today (the only action is "Install uv") but worth guarding. *What* - pythonSetupDeps.ts: ignore an action whose label equals the reserved "Show Logs" (offer the single unambiguous Show Logs button instead of a colliding pair), and dispatch on that guarded `remediation`. *Verification* - TDD: new unit test asserts a colliding "Show Logs" action yields only one button and never opens the URL. - yarn test:unit — 740 passing, 0 failing. - tsc --noEmit clean; yarn test:lint + Prettier clean. Co-authored-by: Isaac
Contributor
Author
|
🤖 Integration tests ❌ 3 of 4 test jobs failed for |
*Why* Review flagged that showError is the failure-reporting path and its sole caller (PythonSetupEnvironmentSetup.setup) does not wrap it, so a rejecting `env.openExternal` when the user clicks "Install uv" would reject the whole setup flow — an unhandled rejection in the error path. *What* - pythonSetupDeps.ts: wrap the `openExternal(remediation.url)` call in try/catch; on failure append the error to the log channel instead of letting the popup reject. *Verification* - TDD: new unit test stubs `env.openExternal` to throw and asserts showError resolves and records the failure to the log. - yarn test:unit — 741 passing, 0 failing. - tsc --noEmit clean; yarn test:lint + Prettier clean. Co-authored-by: Isaac
Contributor
Author
|
🤖 Integration tests triggered for |
*Why* Iteration-2 review (Codex + Claude + Isaac) noted showError's "Install uv" handler only caught a rejected launch: `env.openExternal` can instead *resolve false* when VS Code cannot open the URI, which was silently ignored despite the comment promising to record it. Two smaller nits: a non-Error throw logged "undefined", and the button-order intent was asserted with `.contain` (order not actually verified). *What* - urlUtils.ts: `openExternal` now forwards VS Code's boolean result (Promise<boolean>) so callers can observe a false "could not open". - pythonSetupDeps.ts: log both a false result and a thrown error; use `e instanceof Error ? e.message : String(e)` for the thrown case. - pythonSetupDeps.test.ts: add a resolves-false case; tighten the button-order assertion to deep.equal(["Install uv","Show Logs"]). *Verification* - TDD: new false-resolve test (RED against the old catch-only code); ordering assertion tightened. - yarn test:unit — 742 passing, 0 failing. - tsc --noEmit clean; yarn test:lint + Prettier clean. Co-authored-by: Isaac
Contributor
Author
|
🤖 Integration tests ❌ 3 of 4 test jobs failed for |
…uv-button # Conflicts: # packages/databricks-vscode/src/python-setup/controllers/PythonSetupEnvironmentSetup.ts
rugpanov
had a problem deploying
to
test-trigger-is
August 14, 2026 08:47 — with
GitHub Actions
Error
Contributor
Author
|
🤖 Integration tests ❌ 1 of 35 test jobs failed for |
misha-db
approved these changes
Aug 14, 2026
Contributor
|
If integration tests don't run automatically, an authorized user can run them manually by following the instructions below: Trigger: Inputs:
Checks will be approved automatically on success. |
rugpanov
had a problem deploying
to
test-trigger-is
August 14, 2026 11:03 — with
GitHub Actions
Error
rugpanov
added a commit
that referenced
this pull request
Aug 14, 2026
…unreachable (#2116) ## Why On locked-down corporate machines `pypi.org` is blocked and uv must reach an alternate index/proxy. When it can't, `environments setup-local` fails as `E_PROVISION` and the extension showed a misleading **"dependency version conflict"** message — leaving users with no path forward. ## What - **Detect** uv's package-index connectivity failures and surface tailored guidance: - a popup naming `UV_INDEX_URL` / a pip.conf `index-url`, - a **Configure package index** button linking uv's index docs, - a copy-pasteable remediation block in the output channel (the raw CLI error is still shown). - **Scope precisely**: `E_PROVISION` only, requiring uv's `failed to fetch` index context (excluding git deps) **plus** a host-unreachable symptom — so genuine dependency conflicts, git-dependency fetches, and build-tool stderr are not mislabelled. `E_PYTHON_INSTALL` is deliberately excluded (a managed-CPython download from a different mirror that this guidance can't fix). - **Telemetry**: an optional boolean `indexUnreachable` on `python_env.setup.result` to measure how often a blocked index (vs a conflict) is the cause. ## Verification - `yarn test:unit` — 757 passing, 0 failing (detector, message, action, output-channel remediation, telemetry, and negative cases). - prettier + eslint clean. - Reproduced against **real uv 0.12.3** output (`UV_INDEX_URL` → a refusing endpoint): the genuine `Failed to fetch … Connection refused` text maps to the proxy guidance and button. ## Note Stacks on #2113 (the "Install uv" button), which introduces the popup action-button infra this builds on. The diff shows those commits too until #2113 merges; please merge this after #2113. This pull request and its description were written by Isaac.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
When
environments setup-localfails because uv is not installed (E_UV_MISSING), the error popup only offered Show Logs, leaving the user to find and install uv on their own. This adds a one-click path to uv's install guide, matching how the extension already surfaces the Azure CLI install instructions.What
The popup now shows [Install uv] [Show Logs] on
E_UV_MISSING. Clicking Install uv opens uv's official install page (https://docs.astral.sh/uv/getting-started/installation/) via the existingopenExternalhelper — it deliberately links to the docs (which pick the right installer per platform) rather than running an installer itself. Every other failure code is unchanged (Show Logs only).errorMessages.ts: single-sourceUV_INSTALL_DOCS_URLand a smallgetPythonSetupErrorAction(result)helper returning a{label, url}action only forE_UV_MISSING, so the call-to-action lives next to the message copy.PythonSetupEnvironmentSetup.ts:showErrorgains an optionalactionarg; the failure path passesgetPythonSetupErrorAction(result).pythonSetupDeps.ts: render the remediation button first (before Show Logs) and open its URL when picked.The
actionparam is optional, so the othershowErrorcall sites are unchanged.Verification
yarn test:unit— 739 passing, 0 failing.tsc --noEmitclean;yarn test:lint+ Prettier clean.This pull request and its description were written by Isaac.