Skip to content

Commit

Permalink
Merge pull request #284 from SUSE/api-errors
Browse files Browse the repository at this point in the history
Implement a specific error type for API responses
  • Loading branch information
mssola authored Jan 30, 2025
2 parents 1bb6c2a + 60225e9 commit 24d5bdd
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 22 deletions.
2 changes: 1 addition & 1 deletion cmd/public-api-demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func main() {
err := runDemo(os.Args[1], os.Args[2], os.Args[3], regcode)

if err != nil {
fmt.Printf("ERROR: %s\n", err)
fmt.Printf("%s\n", err)
os.Exit(1)
}
}
36 changes: 36 additions & 0 deletions pkg/connection/api_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package connection

import (
"encoding/json"
"fmt"
"net/http"
)

// ApiError contains all the information for any given API error response. Don't
// build it directly, but use `ErrorFromResponse` instead.
type ApiError struct {
Code int
Message string `json:"error"`
LocalizedMessage string `json:"localized_error"`
}

func (ae *ApiError) Error() string {
if ae.LocalizedMessage != "" {
return fmt.Sprintf("API error: %v (code: %v)", ae.LocalizedMessage, ae.Code)
}
return fmt.Sprintf("API error: %v (code: %v)", ae.Message, ae.Code)
}

// Returns a new ApiError from the given response if it contained an API error
// response. Otherwise it just returns nil.
func ErrorFromResponse(resp *http.Response) *ApiError {
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
return nil
}

ae := &ApiError{Code: resp.StatusCode}
if err := json.NewDecoder(resp.Body).Decode(ae); err != nil {
return nil
}
return ae
}
24 changes: 3 additions & 21 deletions pkg/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ func (conn ApiConnection) Do(request *http.Request) ([]byte, error) {
return nil, err
}

if !successCode(response.StatusCode) {
msg := parseError(response.Body)
return nil, fmt.Errorf("API error: %v (code: %v)", msg, response.StatusCode)
// Check if there was an error from the given API response.
if apiError := ErrorFromResponse(response); apiError != nil {
return nil, apiError
}

data, readErr := io.ReadAll(response.Body)
Expand Down Expand Up @@ -116,21 +116,3 @@ func (conn ApiConnection) setupHTTPClient() *http.Client {

return &http.Client{Transport: transport, Timeout: conn.Options.Timeout}
}

func successCode(code int) bool {
return code >= 200 && code < 300
}

func parseError(body io.Reader) string {
var errResp struct {
Error string `json:"error"`
LocalizedError string `json:"localized_error"`
}
if err := json.NewDecoder(body).Decode(&errResp); err != nil {
return ""
}
if errResp.LocalizedError != "" {
return errResp.LocalizedError
}
return errResp.Error
}

0 comments on commit 24d5bdd

Please sign in to comment.