Skip to content

Commit feb1021

Browse files
committed
review
1 parent a2df5cc commit feb1021

File tree

4 files changed

+63
-33
lines changed

4 files changed

+63
-33
lines changed

src/api.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ export async function waitForBuild(
281281
return updatedWorkspace
282282
}
283283

284-
export async function fetchSSHConfig(restClient: Api, vsc: typeof vscode): Promise<SSHConfigResponse> {
284+
export async function fetchSSHConfig(restClient: Api): Promise<SSHConfigResponse> {
285285
try {
286286
const sshConfig = await restClient.getDeploymentSSHConfig()
287287
return {
@@ -302,10 +302,6 @@ export async function fetchSSHConfig(restClient: Api, vsc: typeof vscode): Promi
302302
ssh_config_options: {},
303303
}
304304
}
305-
case 401: {
306-
vsc.window.showErrorMessage("Your session expired...")
307-
throw error
308-
}
309305
default:
310306
throw error
311307
}

src/commands.ts

+56-16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { isAxiosError } from "axios"
12
import { Api } from "coder/site/src/api/api"
23
import { getErrorMessage } from "coder/site/src/api/errors"
34
import { User, Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated"
@@ -574,16 +575,11 @@ export class Commands {
574575
let sshConfig
575576
try {
576577
// Fetch (or get defaults) for the SSH config.
577-
sshConfig = await fetchSSHConfig(this.restClient, this.vscodeProposed)
578+
sshConfig = await fetchSSHConfig(this.restClient)
578579
} catch (error) {
579-
const message = getErrorMessage(error, "no response from the server")
580-
this.storage.writeToCoderOutputChannel(`Failed to open workspace: ${message}`)
581-
this.vscodeProposed.window.showErrorMessage("Failed to open workspace", {
582-
detail: message,
583-
modal: true,
584-
useCustom: true,
580+
return this.handleInitialRequestError(error, workspaceName, baseUrl, async () => {
581+
await this.openWorkspace(baseUrl, workspaceOwner, workspaceName, workspaceAgent, folderPath, openRecent)
585582
})
586-
return
587583
}
588584

589585
const coderConnectAddr = await maybeCoderConnectAddr(
@@ -669,16 +665,18 @@ export class Commands {
669665
let sshConfig
670666
try {
671667
// Fetch (or get defaults) for the SSH config.
672-
sshConfig = await fetchSSHConfig(this.restClient, this.vscodeProposed)
668+
sshConfig = await fetchSSHConfig(this.restClient)
673669
} catch (error) {
674-
const message = getErrorMessage(error, "no response from the server")
675-
this.storage.writeToCoderOutputChannel(`Failed to open workspace: ${message}`)
676-
this.vscodeProposed.window.showErrorMessage("Failed to open workspace", {
677-
detail: message,
678-
modal: true,
679-
useCustom: true,
670+
return this.handleInitialRequestError(error, workspaceName, baseUrl, async () => {
671+
await this.openDevContainerInner(
672+
baseUrl,
673+
workspaceOwner,
674+
workspaceName,
675+
workspaceAgent,
676+
devContainerName,
677+
devContainerFolder,
678+
)
680679
})
681-
return
682680
}
683681

684682
const coderConnectAddr = await maybeCoderConnectAddr(
@@ -710,4 +708,46 @@ export class Commands {
710708
newWindow,
711709
)
712710
}
711+
712+
private async handleInitialRequestError(
713+
error: unknown,
714+
workspaceName: string,
715+
baseUrl: string,
716+
retryCallback: () => Promise<void>,
717+
) {
718+
if (!isAxiosError(error)) {
719+
throw error
720+
}
721+
switch (error.response?.status) {
722+
case 401: {
723+
const result = await this.vscodeProposed.window.showInformationMessage(
724+
"Your session expired...",
725+
{
726+
useCustom: true,
727+
modal: true,
728+
detail: `You must log in to access ${workspaceName}.`,
729+
},
730+
"Log In",
731+
)
732+
if (!result) {
733+
// User declined to log in.
734+
return
735+
}
736+
// Log in then try again
737+
await vscode.commands.executeCommand("coder.login", baseUrl, undefined, undefined)
738+
await retryCallback()
739+
return
740+
}
741+
default: {
742+
const message = getErrorMessage(error, "no response from the server")
743+
this.storage.writeToCoderOutputChannel(`Failed to open workspace: ${message}`)
744+
this.vscodeProposed.window.showErrorMessage("Failed to open workspace", {
745+
detail: message,
746+
modal: true,
747+
useCustom: true,
748+
})
749+
return
750+
}
751+
}
752+
}
713753
}

src/remote.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ export class Remote {
479479
let sshConfigResponse: SSHConfigResponse
480480
try {
481481
this.storage.writeToCoderOutputChannel("Updating SSH config...")
482-
sshConfigResponse = await fetchSSHConfig(workspaceRestClient, this.vscodeProposed)
482+
sshConfigResponse = await fetchSSHConfig(workspaceRestClient)
483483
await this.updateSSHConfig(
484484
workspaceRestClient,
485485
parts.label,

src/util.ts

+5-11
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,11 @@ export const AuthorityPrefix = "coder-vscode"
2727
export function parseRemoteAuthority(authority: string): AuthorityParts | null {
2828
// The Dev Container authority looks like: vscode://attached-container+containerNameHex@ssh-remote+<ssh host name>
2929
// The SSH authority looks like: vscode://ssh-remote+<ssh host name>
30-
const authorityParts = authority.split("@")
31-
let containerNameHex = undefined
32-
let sshAuthority
33-
if (authorityParts.length === 1) {
34-
sshAuthority = authorityParts[0]
35-
} else if (authorityParts.length === 2 && authorityParts[0].includes("attached-container+")) {
36-
sshAuthority = authorityParts[1]
37-
containerNameHex = authorityParts[0].split("+")[1]
38-
} else {
39-
return null
40-
}
30+
const authorityURI = authority.startsWith("vscode://") ? authority : `vscode://${authority}`
31+
const authorityParts = new URL(authorityURI)
32+
const containerParts = authorityParts.username.split("+")
33+
const containerNameHex = containerParts[1]
34+
const sshAuthority = authorityParts.host
4135
const sshAuthorityParts = sshAuthority.split("+")
4236

4337
// We create SSH host names in a format matching:

0 commit comments

Comments
 (0)