diff --git a/cyclinganalytics/cyclinganalytics.go b/cyclinganalytics/cyclinganalytics.go index ee7990c..99ecfcd 100644 --- a/cyclinganalytics/cyclinganalytics.go +++ b/cyclinganalytics/cyclinganalytics.go @@ -14,13 +14,14 @@ import ( "golang.org/x/oauth2" ) -const baseURL = "https://www.cyclinganalytics.com/api" +const _baseURL = "https://www.cyclinganalytics.com/api" // Client for accessing Cycling Analytics' API type Client struct { - config oauth2.Config - token *oauth2.Token - client *http.Client + config oauth2.Config + token *oauth2.Token + client *http.Client + baseURL string User *UserService Rides *RidesService @@ -39,6 +40,17 @@ func withServices() Option { return func(c *Client) error { c.User = &UserService{client: c} c.Rides = &RidesService{client: c} + if c.baseURL == "" { + c.baseURL = _baseURL + } + return nil + } +} + +// WithBaseURL specifies the base url +func WithBaseURL(baseURL string) Option { + return func(c *Client) error { + c.baseURL = baseURL return nil } } @@ -47,7 +59,7 @@ func (c *Client) newAPIRequest(ctx context.Context, method, uri string, values * if c.token.AccessToken == "" { return nil, errors.New("accessToken required") } - q := fmt.Sprintf("%s/%s", baseURL, uri) + q := fmt.Sprintf("%s/%s", c.baseURL, uri) if values != nil { q = fmt.Sprintf("%s?%s", q, values.Encode()) } diff --git a/cyclinganalytics/cyclinganalytics_with.go b/cyclinganalytics/cyclinganalytics_with.go index b8ac66e..6502d2a 100644 --- a/cyclinganalytics/cyclinganalytics_with.go +++ b/cyclinganalytics/cyclinganalytics_with.go @@ -163,7 +163,20 @@ func (c *Client) do(req *http.Request, v interface{}) error { err = nil // ignore EOF errors caused by empty response body } if httpError { - return obj.(error) + switch q := obj.(type) { + case *Fault: + if q.Code == 0 { + q.Code = res.StatusCode + } + if q.Message == "" { + q.Message = http.StatusText(res.StatusCode) + } + return q + case error: + return q + default: + return q.(error) + } } return err } diff --git a/cyclinganalytics/encoding.go b/cyclinganalytics/encoding.go index 79bbc9f..18bfbab 100644 --- a/cyclinganalytics/encoding.go +++ b/cyclinganalytics/encoding.go @@ -55,7 +55,7 @@ func (r *Ride) GPX() (*gpx.GPX, error) { } trk := gpx.NewTrkType(mls) - trk.Src = baseURL + trk.Src = _baseURL return &gpx.GPX{ Creator: activity.UserAgent, diff --git a/cyclinganalytics/model.go b/cyclinganalytics/model.go index 6b37242..51a6805 100644 --- a/cyclinganalytics/model.go +++ b/cyclinganalytics/model.go @@ -8,6 +8,7 @@ import ( // Fault represents an error response type Fault struct { + Code int `json:"code"` Message string `json:"error"` } diff --git a/rwgps/encoding.go b/rwgps/encoding.go index a8150fe..b7f3c59 100644 --- a/rwgps/encoding.go +++ b/rwgps/encoding.go @@ -30,7 +30,7 @@ func (t *Trip) GeoJSON() (*geojson.Feature, error) { Properties: map[string]interface{}{ "type": t.Type, "name": t.Name, - "source": baseURL, + "source": _baseURL, }, } return g, nil diff --git a/rwgps/model.go b/rwgps/model.go index 82f0a7b..58879f1 100644 --- a/rwgps/model.go +++ b/rwgps/model.go @@ -28,6 +28,7 @@ const ( // Fault is an error type Fault struct { + Code int `json:"code"` Message string `json:"message"` } diff --git a/rwgps/rwgps.go b/rwgps/rwgps.go index 96dadac..b0f05bf 100644 --- a/rwgps/rwgps.go +++ b/rwgps/rwgps.go @@ -17,14 +17,15 @@ import ( const ( apiVersion = "2" - baseURL = "https://ridewithgps.com" + _baseURL = "https://ridewithgps.com" ) // Client for communicating with RWGPS type Client struct { - config oauth2.Config - token *oauth2.Token - client *http.Client + config oauth2.Config + token *oauth2.Token + client *http.Client + baseURL string Users *UsersService Trips *TripsService @@ -38,12 +39,23 @@ func withServices() Option { return func(c *Client) error { c.Users = &UsersService{client: c} c.Trips = &TripsService{client: c} + if c.baseURL == "" { + c.baseURL = _baseURL + } + return nil + } +} + +// WithBaseURL specifies the base url +func WithBaseURL(baseURL string) Option { + return func(c *Client) error { + c.baseURL = baseURL return nil } } func (c *Client) newAPIRequest(ctx context.Context, uri string, params map[string]string) (*http.Request, error) { - u, err := url.Parse(fmt.Sprintf("%s/%s", baseURL, uri)) + u, err := url.Parse(fmt.Sprintf("%s/%s", c.baseURL, uri)) if err != nil { return nil, err } diff --git a/rwgps/rwgps_with.go b/rwgps/rwgps_with.go index e305404..e5feba2 100644 --- a/rwgps/rwgps_with.go +++ b/rwgps/rwgps_with.go @@ -150,7 +150,20 @@ func (c *Client) do(req *http.Request, v interface{}) error { err = nil // ignore EOF errors caused by empty response body } if httpError { - return obj.(error) + switch q := obj.(type) { + case *Fault: + if q.Code == 0 { + q.Code = res.StatusCode + } + if q.Message == "" { + q.Message = http.StatusText(res.StatusCode) + } + return q + case error: + return q + default: + return q.(error) + } } return err } diff --git a/rwgps/trips.go b/rwgps/trips.go index 2396a7b..f468e1f 100644 --- a/rwgps/trips.go +++ b/rwgps/trips.go @@ -153,7 +153,7 @@ func (s *TripsService) Upload(ctx context.Context, file *activity.File) (*Upload return nil, err } - uri := fmt.Sprintf("%s/trips.json", baseURL) + uri := fmt.Sprintf("%s/trips.json", s.client.baseURL) req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, &b) if err != nil { return nil, err diff --git a/strava/model.go b/strava/model.go index 6cd5f05..dbeb3d1 100644 --- a/strava/model.go +++ b/strava/model.go @@ -18,6 +18,7 @@ type Error struct { // Fault contains errors type Fault struct { + Code int `json:"code"` Message string `json:"message"` Errors []*Error `json:"errors"` } diff --git a/strava/strava_with.go b/strava/strava_with.go index 7e448e8..8d159d3 100644 --- a/strava/strava_with.go +++ b/strava/strava_with.go @@ -163,7 +163,20 @@ func (c *Client) do(req *http.Request, v interface{}) error { err = nil // ignore EOF errors caused by empty response body } if httpError { - return obj.(error) + switch q := obj.(type) { + case *Fault: + if q.Code == 0 { + q.Code = res.StatusCode + } + if q.Message == "" { + q.Message = http.StatusText(res.StatusCode) + } + return q + case error: + return q + default: + return q.(error) + } } return err } diff --git a/zwift/model.go b/zwift/model.go index ae6ed48..72705ae 100644 --- a/zwift/model.go +++ b/zwift/model.go @@ -9,6 +9,7 @@ const datetimeFormat = `"2006-01-02T15:04:05+0000"` // Fault represents a Zwift error type Fault struct { + Code int `json:"code"` Message string `json:"message"` } diff --git a/zwift/profile.go b/zwift/profile.go index dc067f2..aea728e 100644 --- a/zwift/profile.go +++ b/zwift/profile.go @@ -22,9 +22,9 @@ func (s *ProfileService) Profile(ctx context.Context, profileID string) (*Profil if err != nil { return nil, err } - var profile *Profile + var profile Profile if err = s.client.do(req, &profile); err != nil { return nil, err } - return profile, err + return &profile, err } diff --git a/zwift/zwift.go b/zwift/zwift.go index eb53f3b..123e178 100644 --- a/zwift/zwift.go +++ b/zwift/zwift.go @@ -13,7 +13,7 @@ import ( //go:generate genwith --do --client --token --ratelimit --package zwift -const baseURL = "https://us-or-rly101.zwift.com" +const _baseURL = "https://us-or-rly101.zwift.com" const userAgent = "CNL/3.4.1 (Darwin Kernel 20.3.0) zwift/1.0.61590 curl/7.64.1" // Endpoint is Zwifts's OAuth 2.0 endpoint @@ -26,8 +26,9 @@ func Endpoint() oauth2.Endpoint { // Client for communicating with Zwift type Client struct { - token *oauth2.Token - client *http.Client + token *oauth2.Token + client *http.Client + baseURL string Auth *AuthService Activity *ActivityService @@ -44,6 +45,17 @@ func withServices() Option { c.Profile = &ProfileService{c} c.Activity = &ActivityService{c} c.token.TokenType = "bearer" + if c.baseURL == "" { + c.baseURL = _baseURL + } + return nil + } +} + +// WithBaseURL specifies the base url +func WithBaseURL(baseURL string) Option { + return func(c *Client) error { + c.baseURL = baseURL return nil } } @@ -52,7 +64,7 @@ func (c *Client) newAPIRequest(ctx context.Context, method, uri string) (*http.R if c.token.AccessToken == "" { return nil, errors.New("accessToken required") } - q := fmt.Sprintf("%s/%s", baseURL, uri) + q := fmt.Sprintf("%s/%s", c.baseURL, uri) u, err := url.Parse(q) if err != nil { return nil, err diff --git a/zwift/zwift_with.go b/zwift/zwift_with.go index 3be1440..76a60d2 100644 --- a/zwift/zwift_with.go +++ b/zwift/zwift_with.go @@ -132,7 +132,20 @@ func (c *Client) do(req *http.Request, v interface{}) error { err = nil // ignore EOF errors caused by empty response body } if httpError { - return obj.(error) + switch q := obj.(type) { + case *Fault: + if q.Code == 0 { + q.Code = res.StatusCode + } + if q.Message == "" { + q.Message = http.StatusText(res.StatusCode) + } + return q + case error: + return q + default: + return q.(error) + } } return err }