Skip to content

Commit 0abd582

Browse files
authored
fix(auth): prevent connection usage when console login is cancelled or fails (#8580)
## Problem - #8537 introduced setupConsoleConnection() and getFunctionWithFallback() to handle authentication fallback for Lambda console-to-IDE transitions. - When developers click "Open in VSCode" and their local AWS profile is invalid, toolkit automatically triggers browser-based console login as a fallback. However, console login requires prerequisites that not all developers can complete. When developers cancel console login, the CLI never writes the connection profile to disk. The Toolkit then attempts to use this non-existent connection, resulting in "Connection does not exist" errors. <img width="471" height="265" alt="problem-before-the-fix-connection-does-not-exist" src="https://github.com/user-attachments/assets/fd973ce1-7b28-4474-8b55-b0408c67e0ce" /> ## Solution - Verify connection exists in `setupConsoleConnection()` after "aws.toolkit.auth.consoleLogin" completes - Show warning message with link to [prerequisites documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sign-in.html#cli-configure-sign-in-prerequisites) when connection verification fails - Throw ToolkitError to halt execution and prevent downstream connection usage <img width="1293" height="302" alt="update-message-with-learnmore" src="https://github.com/user-attachments/assets/a1d35f14-4c42-43c1-8417-b6532ed00e9a" /> <img width="1042" height="625" alt="click-learnmore-show-dialog" src="https://github.com/user-attachments/assets/aace3330-4ea8-4bd8-ad24-e8e956f09c45" /> ### Background The Lambda load-function URI handler enables a seamless workflow where users can click "Open in Visual Studio Code" from the AWS Lambda console to view, edit, and deploy their Lambda functions directly in their preferred IDE. This feature downloads the function code locally, opens it in VS Code, and allows users to make changes and deploy updates back to AWS—all without leaving their development environment. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 91120f2 commit 0abd582

File tree

4 files changed

+45
-1
lines changed

4 files changed

+45
-1
lines changed

packages/core/src/auth/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const localize = nls.loadMessageBundle()
1010

1111
import * as vscode from 'vscode'
1212
import * as localizedText from '../shared/localizedText'
13+
import { consoleSessionHelpUrl } from '../shared/constants'
1314
import { codicon, getIcon } from '../shared/icons'
1415
import { createQuickPick, DataQuickPickItem, showQuickPick } from '../shared/ui/pickerPrompter'
1516
import { isValidResponse } from '../shared/wizards/wizard'
@@ -926,5 +927,19 @@ export async function setupConsoleConnection(profileName: string, region: string
926927
getLogger().info('Auth: Sets up a connection via browser login for profile: %s, region: %s', profileName, region)
927928
await vscode.commands.executeCommand('aws.toolkit.auth.consoleLogin', profileName, region)
928929
const connectionId = getConnectionIdFromProfile(profileName)
930+
// Verify connection was actually created before trying to use it.
931+
// The telemetry wrapper around the console login command catches and logs errors but returns undefined
932+
// instead of re-throwing them. When users cancel (userCancelled=true), the command completes without error,
933+
// so we must check if the connection exists before attempting to use it to avoid confusing downstream errors.
934+
const connection = await Auth.instance.getConnection({ id: connectionId })
935+
if (!connection) {
936+
const message = 'Unable to connect to AWS. Console login was cancelled or did not complete successfully.'
937+
void vscode.window.showWarningMessage(message, localizedText.learnMore).then((selection) => {
938+
if (selection === localizedText.learnMore) {
939+
void vscode.env.openExternal(vscode.Uri.parse(consoleSessionHelpUrl))
940+
}
941+
})
942+
throw new ToolkitError(message, { cancelled: true })
943+
}
929944
await Auth.instance.useConnection({ id: connectionId })
930945
}

packages/core/src/shared/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ export const credentialHelpUrl: string =
4343
'https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-credentials.html'
4444
export const ssoCredentialsHelpUrl: string =
4545
'https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/sso-credentials.html'
46-
46+
export const consoleSessionHelpUrl: string =
47+
'https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sign-in.html#cli-configure-sign-in-prerequisites'
4748
export const supportedLambdaRuntimesUrl: string =
4849
'https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html'
4950
export const createUrlForLambdaFunctionUrl = 'https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html'

packages/core/src/test/auth/utils.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as vscode from 'vscode'
99
import { Auth } from '../../auth/auth'
1010
import { ToolkitError } from '../../shared/errors'
1111
import * as authUtils from '../../auth/utils'
12+
import { getTestWindow } from '../shared/vscode/window'
1213

1314
describe('getConnectionIdFromProfile', function () {
1415
it('constructs connection ID from profile name', function () {
@@ -35,16 +36,39 @@ describe('setupConsoleConnection', function () {
3536

3637
it('creates connection after successful console login', async function () {
3738
const executeCommandStub = sandbox.stub(vscode.commands, 'executeCommand').resolves()
39+
const getConnectionStub = sandbox
40+
.stub(Auth.instance, 'getConnection')
41+
.resolves({ id: 'profile:test-profile' } as any)
3842
const useConnectionStub = sandbox.stub(Auth.instance, 'useConnection').resolves()
3943

4044
await authUtils.setupConsoleConnection('test-profile', 'us-east-1')
4145

4246
assert.ok(executeCommandStub.calledOnceWith('aws.toolkit.auth.consoleLogin', 'test-profile', 'us-east-1'))
47+
assert.ok(getConnectionStub.calledOnceWith({ id: 'profile:test-profile' }))
4348
assert.ok(useConnectionStub.calledOnceWith({ id: 'profile:test-profile' }))
4449
})
4550

51+
it('throws error when connection was not created', async function () {
52+
sandbox.stub(vscode.commands, 'executeCommand').resolves()
53+
sandbox.stub(Auth.instance, 'getConnection').resolves(undefined)
54+
getTestWindow().onDidShowMessage((m) => m.close())
55+
56+
await assert.rejects(
57+
() => authUtils.setupConsoleConnection('test-profile', 'us-east-1'),
58+
(err: ToolkitError) => {
59+
assert.strictEqual(
60+
err.message,
61+
'Unable to connect to AWS. Console login was cancelled or did not complete successfully.'
62+
)
63+
assert.strictEqual(err.cancelled, true)
64+
return true
65+
}
66+
)
67+
})
68+
4669
it('throws error when useConnection fails', async function () {
4770
sandbox.stub(vscode.commands, 'executeCommand').resolves()
71+
sandbox.stub(Auth.instance, 'getConnection').resolves({ id: 'profile:test-profile' } as any)
4872
const error = new Error('useConnection failed')
4973
sandbox.stub(Auth.instance, 'useConnection').rejects(error)
5074

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Lamdbda: Console-to-IDE transition shows \"Connection does not exist\" error when console login is cancelled or fail."
4+
}

0 commit comments

Comments
 (0)