|
| 1 | +import { isAxiosError } from "axios" |
1 | 2 | import { Api } from "coder/site/src/api/api"
|
2 | 3 | import { getErrorMessage } from "coder/site/src/api/errors"
|
3 | 4 | import { User, Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated"
|
@@ -574,16 +575,11 @@ export class Commands {
|
574 | 575 | let sshConfig
|
575 | 576 | try {
|
576 | 577 | // Fetch (or get defaults) for the SSH config.
|
577 |
| - sshConfig = await fetchSSHConfig(this.restClient, this.vscodeProposed) |
| 578 | + sshConfig = await fetchSSHConfig(this.restClient) |
578 | 579 | } 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) |
585 | 582 | })
|
586 |
| - return |
587 | 583 | }
|
588 | 584 |
|
589 | 585 | const coderConnectAddr = await maybeCoderConnectAddr(
|
@@ -669,16 +665,18 @@ export class Commands {
|
669 | 665 | let sshConfig
|
670 | 666 | try {
|
671 | 667 | // Fetch (or get defaults) for the SSH config.
|
672 |
| - sshConfig = await fetchSSHConfig(this.restClient, this.vscodeProposed) |
| 668 | + sshConfig = await fetchSSHConfig(this.restClient) |
673 | 669 | } 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 | + ) |
680 | 679 | })
|
681 |
| - return |
682 | 680 | }
|
683 | 681 |
|
684 | 682 | const coderConnectAddr = await maybeCoderConnectAddr(
|
@@ -710,4 +708,46 @@ export class Commands {
|
710 | 708 | newWindow,
|
711 | 709 | )
|
712 | 710 | }
|
| 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 | + } |
713 | 753 | }
|
0 commit comments