diff --git a/cmd/cmd.go b/cmd/cmd.go index 5f0c70284..36e6ef530 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -1,7 +1,9 @@ package cmd import ( + "encoding/json" "fmt" + "net/http" "io" @@ -70,3 +72,21 @@ func validateUserConfig(cfg *viper.Viper) error { } return nil } + +// decodedAPIError decodes and returns the error message from the API response. +// If the message is blank, it returns a fallback message with the status code. +func decodedAPIError(resp *http.Response) error { + var apiError struct { + Error struct { + Type string `json:"type"` + Message string `json:"message"` + } `json:"error,omitempty"` + } + if err := json.NewDecoder(resp.Body).Decode(&apiError); err != nil { + return fmt.Errorf("failed to parse API error response: %s", err) + } + if apiError.Error.Message != "" { + return fmt.Errorf(apiError.Error.Message) + } + return fmt.Errorf("unexpected API response: %d", resp.StatusCode) +} diff --git a/cmd/submit.go b/cmd/submit.go index 2f9fd9659..d52d83520 100644 --- a/cmd/submit.go +++ b/cmd/submit.go @@ -2,7 +2,6 @@ package cmd import ( "bytes" - "encoding/json" "errors" "fmt" "io" @@ -254,12 +253,7 @@ func (s *submitCmdContext) submit(metadata *workspace.ExerciseMetadata, docs []w defer resp.Body.Close() if resp.StatusCode == http.StatusBadRequest { - var jsonErrBody apiErrorMessage - if err := json.NewDecoder(resp.Body).Decode(&jsonErrBody); err != nil { - return fmt.Errorf("failed to parse error response - %s", err) - } - - return fmt.Errorf(jsonErrBody.Error.Message) + return decodedAPIError(resp) } bb := &bytes.Buffer{} @@ -430,10 +424,3 @@ func (s submitValidator) isRequestor(metadata *workspace.ExerciseMetadata) error func init() { RootCmd.AddCommand(submitCmd) } - -type apiErrorMessage struct { - Error struct { - Type string `json:"type"` - Message string `json:"message"` - } `json:"error,omitempty"` -}