|
| 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