diff --git a/client.go b/client.go index bd5cd49..54eac62 100644 --- a/client.go +++ b/client.go @@ -27,8 +27,22 @@ type Client interface { ListShikonaChangesAPI } -type client struct { - httpClient *http.Client +// Error represents an error returned by the Sumo API. +type Error struct { + StatusCode int + Body []byte + ReadBodyErr error +} + +func (e *Error) Error() string { + switch { + case e.ReadBodyErr != nil: + return fmt.Sprintf("sumoapi: received HTTP %d response; additionally, error reading response body: %v", e.StatusCode, e.ReadBodyErr) + case len(e.Body) == 0: + return fmt.Sprintf("sumoapi: received HTTP %d response with empty body", e.StatusCode) + default: + return fmt.Sprintf("sumoapi: received HTTP %d response: %s", e.StatusCode, string(e.Body)) + } } // Option is a function that configures a Client. @@ -52,6 +66,10 @@ func New(opts ...Option) Client { return client } +type client struct { + httpClient *http.Client +} + func (c *client) doRequest(ctx context.Context, method, path string, query url.Values, obj any) ([]byte, error) { u := fmt.Sprintf("https://sumo-api.com/api%s", path) if len(query) > 0 { @@ -84,13 +102,10 @@ func (c *client) doRequest(ctx context.Context, method, path string, query url.V status := resp.StatusCode if status < 200 || status >= 300 { b, readErr := io.ReadAll(resp.Body) - switch { - case readErr != nil: - return nil, fmt.Errorf("received HTTP %d response; additionally, error reading response body: %w", status, readErr) - case len(b) == 0: - return nil, fmt.Errorf("received HTTP %d response with empty body", status) - default: - return nil, fmt.Errorf("received HTTP %d response: %s", status, string(b)) + return nil, &Error{ + StatusCode: status, + Body: b, + ReadBodyErr: readErr, } }