From 0b68aaab7edf7083679e0d257b4fc2e18aa5e26e Mon Sep 17 00:00:00 2001 From: Jose Garcia Date: Tue, 21 Sep 2021 09:59:16 -0400 Subject: [PATCH] Return error on 202 responses - Start implementing the retry/poll flow --- cmd/ghcs/create.go | 19 ++++++++++++++++++- internal/api/api.go | 7 ++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/cmd/ghcs/create.go b/cmd/ghcs/create.go index 2125176fd..ff3e13962 100644 --- a/cmd/ghcs/create.go +++ b/cmd/ghcs/create.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "strings" + "time" "github.com/AlecAivazis/survey/v2" "github.com/fatih/camelcase" @@ -87,8 +88,20 @@ func create(opts *createOptions) error { log.Println("Creating your codespace...") - codespace, err := apiClient.CreateCodespace(ctx, userResult.User, repository, machine, branch, locationResult.Location) + codespace, err := apiClient.CreateCodespace( + ctx, userResult.User, repository, machine, branch, locationResult.Location, + ) if err != nil { + if err == api.ErrCreateAsyncRetry { + createRetryCtx, cancelRetry := context.WithTimeout(ctx, 2*time.Minute) + defer cancelRetry() + + codespace, err = pollForProvisionedCodespace(createRetryCtx, codespace) + if err != nil { + return fmt.Errorf("error creating codespace after retry: %w", err) + } + } + return fmt.Errorf("error creating codespace: %w", err) } @@ -105,6 +118,10 @@ func create(opts *createOptions) error { return nil } +func pollForProvisionedCodespace(ctx context.Context, provisioningCodespace *api.Codespace) (*api.Codespace, error) { + return nil, nil +} + // showStatus polls the codespace for a list of post create states and their status. It will keep polling // until all states have finished. Once all states have finished, we poll once more to check if any new // states have been introduced and stop polling otherwise. diff --git a/internal/api/api.go b/internal/api/api.go index 1246389e8..df9fd10c7 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -401,6 +401,8 @@ type createCodespaceRequest struct { SkuName string `json:"sku_name"` } +var ErrCreateAsyncRetry = errors.New("initial creation failed, retrying async") + func (a *API) CreateCodespace(ctx context.Context, user *User, repository *Repository, sku, branch, location string) (*Codespace, error) { requestBody, err := json.Marshal(createCodespaceRequest{repository.ID, branch, location, sku}) if err != nil { @@ -424,8 +426,11 @@ func (a *API) CreateCodespace(ctx context.Context, user *User, repository *Repos return nil, fmt.Errorf("error reading response body: %w", err) } - if resp.StatusCode > http.StatusAccepted { + switch { + case resp.StatusCode > http.StatusAccepted: return nil, jsonErrorResponse(b) + case resp.StatusCode == http.StatusAccepted: + return nil, ErrCreateAsyncRetry } var response Codespace