api: return structured error for failed API calls
`fmt.Errorf` hides information and makes it hard to test for specific conditions in returned error. Return a structured error instead. Signed-off-by: Pavel Borzenkov <pavel.borzenkov@gmail.com>
This commit is contained in:
parent
aa8f8e8904
commit
c66eebc6fb
2 changed files with 30 additions and 1 deletions
|
|
@ -157,6 +157,17 @@ func (gr GraphQLErrorResponse) Error() string {
|
|||
return fmt.Sprintf("graphql error: '%s'", strings.Join(errorMessages, ", "))
|
||||
}
|
||||
|
||||
// HTTPError is an error returned by a failed API call
|
||||
type HTTPError struct {
|
||||
Code int
|
||||
URL string
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e HTTPError) Error() string {
|
||||
return fmt.Sprintf("http error, '%s' failed (%d): '%s'", e.URL, e.Code, e.Message)
|
||||
}
|
||||
|
||||
// Returns whether or not scopes are present, appID, and error
|
||||
func (c Client) HasScopes(wantedScopes ...string) (bool, string, error) {
|
||||
url := "https://api.github.com/user"
|
||||
|
|
@ -298,7 +309,11 @@ func handleHTTPError(resp *http.Response) error {
|
|||
message = parsedBody.Message
|
||||
}
|
||||
|
||||
return fmt.Errorf("http error, '%s' failed (%d): '%s'", resp.Request.URL, resp.StatusCode, message)
|
||||
return HTTPError{
|
||||
Code: resp.StatusCode,
|
||||
URL: resp.Request.URL.String(),
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
var jsonTypeRE = regexp.MustCompile(`[/+]json($|;)`)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package api
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
|
@ -66,3 +67,16 @@ func TestRESTGetDelete(t *testing.T) {
|
|||
err := client.REST("DELETE", "applications/CLIENTID/grant", r, nil)
|
||||
eq(t, err, nil)
|
||||
}
|
||||
|
||||
func TestRESTError(t *testing.T) {
|
||||
http := &httpmock.Registry{}
|
||||
client := NewClient(ReplaceTripper(http))
|
||||
|
||||
http.StubResponse(422, bytes.NewBufferString(`{"message": "OH NO"}`))
|
||||
|
||||
var httpErr HTTPError
|
||||
err := client.REST("DELETE", "/repos/branch", nil, nil)
|
||||
if err == nil || !errors.As(err, &httpErr) || httpErr.Code != 422 {
|
||||
t.Fatalf("got %q", err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue