deal with Start errors, non-JSON

This commit is contained in:
Alan Donovan 2021-08-27 18:01:52 -04:00
parent 4545e11ffc
commit dcf4f041e9

View file

@ -1,5 +1,11 @@
package api
// For descriptions of service interfaces, see:
// - https://online.visualstudio.com/api/swagger (for visualstudio.com)
// - https://docs.github.com/en/rest/reference/repos (for api.github.com)
// - https://github.com/github/github/blob/master/app/api/codespaces.rb (for vscs_internal)
// TODO(adonovan): replace the last link with a public doc URL when available.
import (
"bytes"
"context"
@ -29,10 +35,6 @@ type User struct {
Login string `json:"login"`
}
type errResponse struct {
Message string `json:"message"`
}
func (a *API) GetUser(ctx context.Context) (*User, error) {
req, err := http.NewRequest(http.MethodGet, githubAPI+"/user", nil)
if err != nil {
@ -52,7 +54,7 @@ func (a *API) GetUser(ctx context.Context) (*User, error) {
}
if resp.StatusCode != http.StatusOK {
return nil, a.errorResponse(b)
return nil, jsonErrorResponse(b)
}
var response User
@ -63,8 +65,10 @@ func (a *API) GetUser(ctx context.Context) (*User, error) {
return &response, nil
}
func (a *API) errorResponse(b []byte) error {
var response errResponse
func jsonErrorResponse(b []byte) error {
var response struct {
Message string `json:"message"`
}
if err := json.Unmarshal(b, &response); err != nil {
return fmt.Errorf("error unmarshaling error response: %v", err)
}
@ -95,7 +99,7 @@ func (a *API) GetRepository(ctx context.Context, nwo string) (*Repository, error
}
if resp.StatusCode != http.StatusOK {
return nil, a.errorResponse(b)
return nil, jsonErrorResponse(b)
}
var response Repository
@ -162,7 +166,7 @@ func (a *API) ListCodespaces(ctx context.Context, user *User) (Codespaces, error
}
if resp.StatusCode != http.StatusOK {
return nil, a.errorResponse(b)
return nil, jsonErrorResponse(b)
}
response := struct {
@ -210,7 +214,7 @@ func (a *API) GetCodespaceToken(ctx context.Context, ownerLogin, codespaceName s
}
if resp.StatusCode != http.StatusOK {
return "", a.errorResponse(b)
return "", jsonErrorResponse(b)
}
var response getCodespaceTokenResponse
@ -244,7 +248,7 @@ func (a *API) GetCodespace(ctx context.Context, token, owner, codespace string)
}
if resp.StatusCode != http.StatusOK {
return nil, a.errorResponse(b)
return nil, jsonErrorResponse(b)
}
var response Codespace
@ -277,11 +281,12 @@ func (a *API) StartCodespace(ctx context.Context, token string, codespace *Codes
return fmt.Errorf("error reading response body: %v", err)
}
// TODO(adonovan): the status code proxied from VSCS may distinguish
// "already running" from "fresh start". Find out what code it uses
// and allow it too.
if resp.StatusCode != http.StatusOK {
return a.errorResponse(b)
// Error response is numeric code and/or string message, not JSON.
if len(b) > 100 {
b = append(b[:97], "..."...)
}
return fmt.Errorf("failed to start codespace: %s", b)
}
return nil
@ -309,7 +314,7 @@ func (a *API) GetCodespaceRegionLocation(ctx context.Context) (string, error) {
}
if resp.StatusCode != http.StatusOK {
return "", a.errorResponse(b)
return "", jsonErrorResponse(b)
}
var response getCodespaceRegionLocationResponse
@ -351,7 +356,7 @@ func (a *API) GetCodespacesSkus(ctx context.Context, user *User, repository *Rep
}
if resp.StatusCode != http.StatusOK {
return nil, a.errorResponse(b)
return nil, jsonErrorResponse(b)
}
response := struct {
@ -395,7 +400,7 @@ func (a *API) CreateCodespace(ctx context.Context, user *User, repository *Repos
}
if resp.StatusCode > http.StatusAccepted {
return nil, a.errorResponse(b)
return nil, jsonErrorResponse(b)
}
var response Codespace
@ -424,7 +429,7 @@ func (a *API) DeleteCodespace(ctx context.Context, user *User, token, codespaceN
if err != nil {
return fmt.Errorf("error reading response body: %v", err)
}
return a.errorResponse(b)
return jsonErrorResponse(b)
}
return nil
@ -461,7 +466,7 @@ func (a *API) GetCodespaceRepositoryContents(ctx context.Context, codespace *Cod
}
if resp.StatusCode != http.StatusOK {
return nil, a.errorResponse(b)
return nil, jsonErrorResponse(b)
}
var response getCodespaceRepositoryContentsResponse