Skip to content
This repository has been archived by the owner on Jul 4, 2024. It is now read-only.

Commit

Permalink
Improved humanitec error handling (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
johanneswuerbach committed Nov 13, 2023
2 parents 3b49044 + 6e1428a commit 0cf7c6a
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 9 deletions.
25 changes: 25 additions & 0 deletions internal/command/delta.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"net/http"
"os"
"path/filepath"
"regexp"

"github.com/score-spec/score-humanitec/internal/humanitec"
api "github.com/score-spec/score-humanitec/internal/humanitec_go/client"
Expand Down Expand Up @@ -74,6 +75,11 @@ func delta(cmd *cobra.Command, args []string) error {
return err
}

// Validate the ID
if err := validateIDs(); err != nil {
return err
}

// Prepare a new deployment
//
log.Print("Preparing a new deployment...\n")
Expand Down Expand Up @@ -124,3 +130,22 @@ func delta(cmd *cobra.Command, args []string) error {

return nil
}

var validID = regexp.MustCompile(`^[a-z0-9](?:-?[a-z0-9]+)+$`)

func validateIDs() error {
ids := []struct {
name string
id string
}{
{"organization", orgID}, {"application", appID}, {"environment", envID},
}

for _, e := range ids {
if !validID.MatchString(e.id) {
return fmt.Errorf("invalid %s id '%s'. Did you use the %s name instead of the id?", e.name, e.id, e.name)
}
}

return nil
}
8 changes: 6 additions & 2 deletions internal/humanitec_go/client/deltas.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (api *apiClient) CreateDelta(ctx context.Context, orgID, appID string, delt
}

default:
return nil, fmt.Errorf("humanitec api: %s %s: HTTP %d - %s", req.Method, req.BaseURL, resp.StatusCode, http.StatusText(resp.StatusCode))
return nil, resError(req, resp)
}
}

Expand Down Expand Up @@ -100,6 +100,10 @@ func (api *apiClient) UpdateDelta(ctx context.Context, orgID string, appID strin
return &res, nil
}
default:
return nil, fmt.Errorf("humanitec api: %s %s: HTTP %d - %s", req.Method, req.BaseURL, resp.StatusCode, http.StatusText(resp.StatusCode))
return nil, resError(req, resp)
}
}

func resError(req rest.Request, resp *rest.Response) error {
return fmt.Errorf("humanitec api: %s %s: unexpected response status %d - %s\n%s", req.Method, req.BaseURL, resp.StatusCode, http.StatusText(resp.StatusCode), resp.Body)
}
6 changes: 4 additions & 2 deletions internal/humanitec_go/client/deltas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ func TestCreateDelta(t *testing.T) {
{
Name: "Should handle API errors",
StatusCode: http.StatusInternalServerError,
ExpectedError: errors.New("HTTP 500"),
ExpectedError: errors.New("unexpected response status 500 - Internal Server Error\nerror details"),
Response: []byte(`error details`),
},
{
Name: "Should handle response parsing errors",
Expand Down Expand Up @@ -208,6 +209,7 @@ func TestUpdateDelta_fail(t *testing.T) {
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("{\"error\": \"Not Found\"}"))
},
),
)
Expand All @@ -219,5 +221,5 @@ func TestUpdateDelta_fail(t *testing.T) {
{Modules: humanitec.ModuleDeltas{}},
})
assert.Nil(t, res)
assert.ErrorContains(t, err, ": HTTP 404 - Not Found")
assert.ErrorContains(t, err, ": unexpected response status 404 - Not Found\n{\"error\": \"Not Found\"}")
}
2 changes: 1 addition & 1 deletion internal/humanitec_go/client/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ func (api *apiClient) StartDeployment(ctx context.Context, orgID, appID, envID s

fallthrough
default:
return nil, fmt.Errorf("humanitec api: %s %s: HTTP %d - %s", req.Method, req.BaseURL, resp.StatusCode, http.StatusText(resp.StatusCode))
return nil, resError(req, resp)
}
}
6 changes: 4 additions & 2 deletions internal/humanitec_go/client/deployments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ func TestStartDeployment(t *testing.T) {
{
Name: "Should handle API errors",
StatusCode: []int{http.StatusInternalServerError},
ExpectedError: errors.New("HTTP 500"),
Response: []byte(`error details`),
ExpectedError: errors.New("unexpected response status 500 - Internal Server Error\nerror details"),
},
{
Name: "Should handle response parsing errors",
Expand All @@ -99,7 +100,8 @@ func TestStartDeployment(t *testing.T) {
},
Retry: false,
StatusCode: []int{http.StatusConflict},
ExpectedError: errors.New("HTTP 409"),
Response: []byte(`conflict details`),
ExpectedError: errors.New("unexpected response status 409 - Conflict\nconflict details"),
},
{
Name: "Should retry conflict errors with retry",
Expand Down
2 changes: 1 addition & 1 deletion internal/humanitec_go/client/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ func (api *apiClient) ListResourceTypes(ctx context.Context, orgID string) ([]hu
}

default:
return nil, fmt.Errorf("humanitec api: %s %s: HTTP %d - %s", req.Method, req.BaseURL, resp.StatusCode, http.StatusText(resp.StatusCode))
return nil, resError(req, resp)
}
}
3 changes: 2 additions & 1 deletion internal/humanitec_go/client/resources_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ func TestListResourceTypes(t *testing.T) {
{
Name: "Should handle API errors",
StatusCode: http.StatusInternalServerError,
ExpectedError: errors.New("HTTP 500"),
ExpectedError: errors.New("unexpected response status 500 - Internal Server Error\nerror details"),
Response: []byte(`error details`),
},
{
Name: "Should handle response parsing errors",
Expand Down

0 comments on commit 0cf7c6a

Please sign in to comment.