Skip to content

Commit 1b58bfc

Browse files
authoredOct 24, 2024
Feature: Adding standardize response error (#225)
* Adding standardize request error To help simplify and address how errors from request are handled, this returns an error type that allows for deeper introspection from external packages. * Correcting AsResponseError method * Adding slices contains
1 parent ebdaa3e commit 1b58bfc

26 files changed

+600
-719
lines changed
 

‎alertmuting.go

+17-28
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -25,16 +24,13 @@ func (c *Client) CreateAlertMutingRule(ctx context.Context, muteRequest *alertmu
2524
}
2625

2726
resp, err := c.doRequest(ctx, "POST", AlertMutingRuleAPIURL, nil, bytes.NewReader(payload))
28-
if resp != nil {
29-
defer resp.Body.Close()
30-
}
3127
if err != nil {
3228
return nil, err
3329
}
30+
defer resp.Body.Close()
3431

35-
if resp.StatusCode != http.StatusCreated {
36-
message, _ := ioutil.ReadAll(resp.Body)
37-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
32+
if err = newResponseError(resp, http.StatusCreated); err != nil {
33+
return nil, err
3834
}
3935

4036
finalRule := &alertmuting.AlertMutingRule{}
@@ -48,16 +44,13 @@ func (c *Client) CreateAlertMutingRule(ctx context.Context, muteRequest *alertmu
4844
// DeleteAlertMutingRule deletes an alert muting rule.
4945
func (c *Client) DeleteAlertMutingRule(ctx context.Context, name string) error {
5046
resp, err := c.doRequest(ctx, "DELETE", AlertMutingRuleAPIURL+"/"+name, nil, nil)
51-
if resp != nil {
52-
defer resp.Body.Close()
53-
}
5447
if err != nil {
5548
return err
5649
}
50+
defer resp.Body.Close()
5751

58-
if resp.StatusCode != http.StatusNoContent {
59-
message, _ := ioutil.ReadAll(resp.Body)
60-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
52+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
53+
return err
6154
}
6255
_, _ = io.Copy(ioutil.Discard, resp.Body)
6356

@@ -67,16 +60,13 @@ func (c *Client) DeleteAlertMutingRule(ctx context.Context, name string) error {
6760
// GetAlertMutingRule gets an alert muting rule.
6861
func (c *Client) GetAlertMutingRule(ctx context.Context, id string) (*alertmuting.AlertMutingRule, error) {
6962
resp, err := c.doRequest(ctx, "GET", AlertMutingRuleAPIURL+"/"+id, nil, nil)
70-
if resp != nil {
71-
defer resp.Body.Close()
72-
}
7363
if err != nil {
7464
return nil, err
7565
}
66+
defer resp.Body.Close()
7667

77-
if resp.StatusCode != http.StatusOK {
78-
message, _ := ioutil.ReadAll(resp.Body)
79-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
68+
if err = newResponseError(resp, http.StatusOK); err != nil {
69+
return nil, err
8070
}
8171

8272
finalRule := &alertmuting.AlertMutingRule{}
@@ -95,16 +85,13 @@ func (c *Client) UpdateAlertMutingRule(ctx context.Context, id string, muteReque
9585
}
9686

9787
resp, err := c.doRequest(ctx, "PUT", AlertMutingRuleAPIURL+"/"+id, nil, bytes.NewReader(payload))
98-
if resp != nil {
99-
defer resp.Body.Close()
100-
}
10188
if err != nil {
10289
return nil, err
10390
}
91+
defer resp.Body.Close()
10492

105-
if resp.StatusCode != http.StatusOK {
106-
message, _ := ioutil.ReadAll(resp.Body)
107-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
93+
if err = newResponseError(resp, http.StatusOK); err != nil {
94+
return nil, err
10895
}
10996

11097
finalRule := &alertmuting.AlertMutingRule{}
@@ -124,12 +111,14 @@ func (c *Client) SearchAlertMutingRules(ctx context.Context, include string, lim
124111
params.Add("offset", strconv.Itoa(offset))
125112

126113
resp, err := c.doRequest(ctx, "GET", AlertMutingRuleAPIURL, params, nil)
127-
if resp != nil {
128-
defer resp.Body.Close()
129-
}
130114
if err != nil {
131115
return nil, err
132116
}
117+
defer resp.Body.Close()
118+
119+
if err = newResponseError(resp, http.StatusOK); err != nil {
120+
return nil, err
121+
}
133122

134123
finalRules := &alertmuting.SearchResult{}
135124

‎aws_cloudwatch_integration.go

+12-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -20,16 +19,13 @@ func (c *Client) CreateAWSCloudWatchIntegration(ctx context.Context, acwi *integ
2019
}
2120

2221
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
23-
if resp != nil {
24-
defer resp.Body.Close()
25-
}
2622
if err != nil {
2723
return nil, err
2824
}
25+
defer resp.Body.Close()
2926

30-
if resp.StatusCode != http.StatusOK {
31-
message, _ := ioutil.ReadAll(resp.Body)
32-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
27+
if err = newResponseError(resp, http.StatusOK); err != nil {
28+
return nil, err
3329
}
3430

3531
finalIntegration := integration.AwsCloudWatchIntegration{}
@@ -43,16 +39,13 @@ func (c *Client) CreateAWSCloudWatchIntegration(ctx context.Context, acwi *integ
4339
// GetAWSCloudWatchIntegration retrieves an AWS CloudWatch integration.
4440
func (c *Client) GetAWSCloudWatchIntegration(ctx context.Context, id string) (*integration.AwsCloudWatchIntegration, error) {
4541
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
46-
if resp != nil {
47-
defer resp.Body.Close()
48-
}
4942
if err != nil {
5043
return nil, err
5144
}
45+
defer resp.Body.Close()
5246

53-
if resp.StatusCode != http.StatusOK {
54-
message, _ := ioutil.ReadAll(resp.Body)
55-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
47+
if err = newResponseError(resp, http.StatusOK); err != nil {
48+
return nil, err
5649
}
5750

5851
finalIntegration := integration.AwsCloudWatchIntegration{}
@@ -71,16 +64,13 @@ func (c *Client) UpdateAWSCloudWatchIntegration(ctx context.Context, id string,
7164
}
7265

7366
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
7767
if err != nil {
7868
return nil, err
7969
}
70+
defer resp.Body.Close()
8071

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
72+
if err = newResponseError(resp, http.StatusOK); err != nil {
73+
return nil, err
8474
}
8575

8676
finalIntegration := integration.AwsCloudWatchIntegration{}
@@ -94,16 +84,13 @@ func (c *Client) UpdateAWSCloudWatchIntegration(ctx context.Context, id string,
9484
// DeleteAWSCloudWatchIntegration deletes an AWS CloudWatch integration.
9585
func (c *Client) DeleteAWSCloudWatchIntegration(ctx context.Context, id string) error {
9686
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10087
if err != nil {
10188
return err
10289
}
90+
defer resp.Body.Close()
10391

104-
if resp.StatusCode != http.StatusNoContent {
105-
message, _ := ioutil.ReadAll(resp.Body)
106-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
92+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
93+
return err
10794
}
10895
_, _ = io.Copy(ioutil.Discard, resp.Body)
10996

‎azure_integration.go

+13-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -20,16 +19,13 @@ func (c *Client) CreateAzureIntegration(ctx context.Context, acwi *integration.A
2019
}
2120

2221
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
23-
if resp != nil {
24-
defer resp.Body.Close()
25-
}
2622
if err != nil {
2723
return nil, err
2824
}
25+
defer resp.Body.Close()
2926

30-
if resp.StatusCode != http.StatusOK {
31-
message, _ := ioutil.ReadAll(resp.Body)
32-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
27+
if err = newResponseError(resp, http.StatusOK); err != nil {
28+
return nil, err
3329
}
3430

3531
finalIntegration := integration.AzureIntegration{}
@@ -43,16 +39,13 @@ func (c *Client) CreateAzureIntegration(ctx context.Context, acwi *integration.A
4339
// GetAzureIntegration retrieves an Azure integration.
4440
func (c *Client) GetAzureIntegration(ctx context.Context, id string) (*integration.AzureIntegration, error) {
4541
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
46-
if resp != nil {
47-
defer resp.Body.Close()
48-
}
4942
if err != nil {
5043
return nil, err
5144
}
45+
defer resp.Body.Close()
5246

53-
if resp.StatusCode != http.StatusOK {
54-
message, _ := ioutil.ReadAll(resp.Body)
55-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
47+
if err = newResponseError(resp, http.StatusOK); err != nil {
48+
return nil, err
5649
}
5750

5851
finalIntegration := integration.AzureIntegration{}
@@ -71,16 +64,14 @@ func (c *Client) UpdateAzureIntegration(ctx context.Context, id string, acwi *in
7164
}
7265

7366
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
67+
7768
if err != nil {
7869
return nil, err
7970
}
71+
defer resp.Body.Close()
8072

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
73+
if err = newResponseError(resp, http.StatusOK); err != nil {
74+
return nil, err
8475
}
8576

8677
finalIntegration := integration.AzureIntegration{}
@@ -94,16 +85,13 @@ func (c *Client) UpdateAzureIntegration(ctx context.Context, id string, acwi *in
9485
// DeleteAzureIntegration deletes an Azure integration.
9586
func (c *Client) DeleteAzureIntegration(ctx context.Context, id string) error {
9687
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10088
if err != nil {
10189
return err
10290
}
91+
defer resp.Body.Close()
10392

104-
if resp.StatusCode != http.StatusNoContent {
105-
message, _ := ioutil.ReadAll(resp.Body)
106-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
93+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
94+
return err
10795
}
10896
_, _ = io.Copy(ioutil.Discard, resp.Body)
10997

‎chart.go

+15-31
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"errors"
8-
"fmt"
97
"io"
108
"io/ioutil"
119
"net/http"
@@ -26,16 +24,13 @@ func (c *Client) CreateChart(ctx context.Context, chartRequest *chart.CreateUpda
2624
}
2725

2826
resp, err := c.doRequest(ctx, "POST", ChartAPIURL, nil, bytes.NewReader(payload))
29-
if resp != nil {
30-
defer resp.Body.Close()
31-
}
3227
if err != nil {
3328
return nil, err
3429
}
30+
defer resp.Body.Close()
3531

36-
if resp.StatusCode != http.StatusOK {
37-
message, _ := ioutil.ReadAll(resp.Body)
38-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
32+
if err = newResponseError(resp, http.StatusOK); err != nil {
33+
return nil, err
3934
}
4035

4136
finalChart := &chart.Chart{}
@@ -49,15 +44,13 @@ func (c *Client) CreateChart(ctx context.Context, chartRequest *chart.CreateUpda
4944
// DeleteChart deletes a chart.
5045
func (c *Client) DeleteChart(ctx context.Context, id string) error {
5146
resp, err := c.doRequest(ctx, "DELETE", ChartAPIURL+"/"+id, nil, nil)
52-
if resp != nil {
53-
defer resp.Body.Close()
54-
}
5547
if err != nil {
5648
return err
5749
}
50+
defer resp.Body.Close()
5851

59-
if resp.StatusCode != http.StatusOK {
60-
return errors.New("Unexpected status code: " + resp.Status)
52+
if err = newResponseError(resp, http.StatusOK); err != nil {
53+
return err
6154
}
6255
_, _ = io.Copy(ioutil.Discard, resp.Body)
6356

@@ -67,16 +60,13 @@ func (c *Client) DeleteChart(ctx context.Context, id string) error {
6760
// GetChart gets a chart.
6861
func (c *Client) GetChart(ctx context.Context, id string) (*chart.Chart, error) {
6962
resp, err := c.doRequest(ctx, "GET", ChartAPIURL+"/"+id, nil, nil)
70-
if resp != nil {
71-
defer resp.Body.Close()
72-
}
7363
if err != nil {
7464
return nil, err
7565
}
66+
defer resp.Body.Close()
7667

77-
if resp.StatusCode != http.StatusOK {
78-
message, _ := ioutil.ReadAll(resp.Body)
79-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
68+
if err = newResponseError(resp, http.StatusOK); err != nil {
69+
return nil, err
8070
}
8171

8272
finalChart := &chart.Chart{}
@@ -95,16 +85,13 @@ func (c *Client) UpdateChart(ctx context.Context, id string, chartRequest *chart
9585
}
9686

9787
resp, err := c.doRequest(ctx, "PUT", ChartAPIURL+"/"+id, nil, bytes.NewReader(payload))
98-
if resp != nil {
99-
defer resp.Body.Close()
100-
}
10188
if err != nil {
10289
return nil, err
10390
}
91+
defer resp.Body.Close()
10492

105-
if resp.StatusCode != http.StatusOK {
106-
message, _ := ioutil.ReadAll(resp.Body)
107-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
93+
if err = newResponseError(resp, http.StatusOK); err != nil {
94+
return nil, err
10895
}
10996

11097
finalChart := &chart.Chart{}
@@ -128,16 +115,13 @@ func (c *Client) SearchCharts(ctx context.Context, limit int, name string, offse
128115
}
129116

130117
resp, err := c.doRequest(ctx, "GET", ChartAPIURL, params, nil)
131-
if resp != nil {
132-
defer resp.Body.Close()
133-
}
134118
if err != nil {
135119
return nil, err
136120
}
121+
defer resp.Body.Close()
137122

138-
if resp.StatusCode != http.StatusOK {
139-
message, _ := ioutil.ReadAll(resp.Body)
140-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
123+
if err = newResponseError(resp, http.StatusOK); err != nil {
124+
return nil, err
141125
}
142126

143127
finalCharts := &chart.SearchResult{}

‎dashboard.go

+15-31
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -27,16 +26,13 @@ func (c *Client) CreateDashboard(ctx context.Context, dashboardRequest *dashboar
2726
}
2827

2928
resp, err := c.doRequest(ctx, "POST", DashboardAPIURL, nil, bytes.NewReader(payload))
30-
if resp != nil {
31-
defer resp.Body.Close()
32-
}
3329
if err != nil {
3430
return nil, err
3531
}
32+
defer resp.Body.Close()
3633

37-
if resp.StatusCode != http.StatusOK {
38-
message, _ := ioutil.ReadAll(resp.Body)
39-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
34+
if err = newResponseError(resp, http.StatusOK); err != nil {
35+
return nil, err
4036
}
4137

4238
finalDashboard := &dashboard.Dashboard{}
@@ -50,16 +46,13 @@ func (c *Client) CreateDashboard(ctx context.Context, dashboardRequest *dashboar
5046
// DeleteDashboard deletes a dashboard.
5147
func (c *Client) DeleteDashboard(ctx context.Context, id string) error {
5248
resp, err := c.doRequest(ctx, "DELETE", DashboardAPIURL+"/"+id, nil, nil)
53-
if resp != nil {
54-
defer resp.Body.Close()
55-
}
5649
if err != nil {
5750
return err
5851
}
52+
defer resp.Body.Close()
5953

60-
if resp.StatusCode != http.StatusOK {
61-
message, _ := ioutil.ReadAll(resp.Body)
62-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
54+
if err = newResponseError(resp, http.StatusOK); err != nil {
55+
return err
6356
}
6457
_, _ = io.Copy(ioutil.Discard, resp.Body)
6558

@@ -69,16 +62,13 @@ func (c *Client) DeleteDashboard(ctx context.Context, id string) error {
6962
// GetDashboard gets a dashboard.
7063
func (c *Client) GetDashboard(ctx context.Context, id string) (*dashboard.Dashboard, error) {
7164
resp, err := c.doRequest(ctx, "GET", DashboardAPIURL+"/"+id, nil, nil)
72-
if resp != nil {
73-
defer resp.Body.Close()
74-
}
7565
if err != nil {
7666
return nil, err
7767
}
68+
defer resp.Body.Close()
7869

79-
if resp.StatusCode != http.StatusOK {
80-
message, _ := ioutil.ReadAll(resp.Body)
81-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
70+
if err = newResponseError(resp, http.StatusOK); err != nil {
71+
return nil, err
8272
}
8373

8474
finalDashboard := &dashboard.Dashboard{}
@@ -97,16 +87,13 @@ func (c *Client) UpdateDashboard(ctx context.Context, id string, dashboardReques
9787
}
9888

9989
resp, err := c.doRequest(ctx, "PUT", DashboardAPIURL+"/"+id, nil, bytes.NewReader(payload))
100-
if resp != nil {
101-
defer resp.Body.Close()
102-
}
10390
if err != nil {
10491
return nil, err
10592
}
93+
defer resp.Body.Close()
10694

107-
if resp.StatusCode != http.StatusOK {
108-
message, _ := ioutil.ReadAll(resp.Body)
109-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
95+
if err = newResponseError(resp, http.StatusOK); err != nil {
96+
return nil, err
11097
}
11198

11299
finalDashboard := &dashboard.Dashboard{}
@@ -126,16 +113,13 @@ func (c *Client) SearchDashboard(ctx context.Context, limit int, name string, of
126113
params.Add("tags", tags)
127114

128115
resp, err := c.doRequest(ctx, "GET", DashboardAPIURL, params, nil)
129-
if resp != nil {
130-
defer resp.Body.Close()
131-
}
132116
if err != nil {
133117
return nil, err
134118
}
119+
defer resp.Body.Close()
135120

136-
if resp.StatusCode != http.StatusOK {
137-
message, _ := ioutil.ReadAll(resp.Body)
138-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
121+
if err = newResponseError(resp, http.StatusOK); err != nil {
122+
return nil, err
139123
}
140124

141125
finalDashboards := &dashboard.SearchResult{}

‎dashboardgroup.go

+15-31
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -32,16 +31,13 @@ func (c *Client) CreateDashboardGroup(ctx context.Context, dashboardGroupRequest
3231
}
3332

3433
resp, err := c.doRequest(ctx, "POST", DashboardGroupAPIURL, params, bytes.NewReader(payload))
35-
if resp != nil {
36-
defer resp.Body.Close()
37-
}
3834
if err != nil {
3935
return nil, err
4036
}
37+
defer resp.Body.Close()
4138

42-
if resp.StatusCode != http.StatusOK {
43-
message, _ := ioutil.ReadAll(resp.Body)
44-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
39+
if err = newResponseError(resp, http.StatusOK); err != nil {
40+
return nil, err
4541
}
4642

4743
finalDashboardGroup := &dashboard_group.DashboardGroup{}
@@ -55,16 +51,13 @@ func (c *Client) CreateDashboardGroup(ctx context.Context, dashboardGroupRequest
5551
// DeleteDashboardGroup deletes a dashboard.
5652
func (c *Client) DeleteDashboardGroup(ctx context.Context, id string) error {
5753
resp, err := c.doRequest(ctx, "DELETE", DashboardGroupAPIURL+"/"+id, nil, nil)
58-
if resp != nil {
59-
defer resp.Body.Close()
60-
}
6154
if err != nil {
6255
return err
6356
}
57+
defer resp.Body.Close()
6458

65-
if resp.StatusCode != http.StatusNoContent {
66-
message, _ := ioutil.ReadAll(resp.Body)
67-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
59+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
60+
return err
6861
}
6962
_, _ = io.Copy(ioutil.Discard, resp.Body)
7063

@@ -74,16 +67,13 @@ func (c *Client) DeleteDashboardGroup(ctx context.Context, id string) error {
7467
// GetDashboardGroup gets a dashboard group.
7568
func (c *Client) GetDashboardGroup(ctx context.Context, id string) (*dashboard_group.DashboardGroup, error) {
7669
resp, err := c.doRequest(ctx, "GET", DashboardGroupAPIURL+"/"+id, nil, nil)
77-
if resp != nil {
78-
defer resp.Body.Close()
79-
}
8070
if err != nil {
8171
return nil, err
8272
}
73+
defer resp.Body.Close()
8374

84-
if resp.StatusCode != http.StatusOK {
85-
message, _ := ioutil.ReadAll(resp.Body)
86-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
75+
if err = newResponseError(resp, http.StatusOK); err != nil {
76+
return nil, err
8777
}
8878

8979
finalDashboardGroup := &dashboard_group.DashboardGroup{}
@@ -102,16 +92,13 @@ func (c *Client) UpdateDashboardGroup(ctx context.Context, id string, dashboardG
10292
}
10393

10494
resp, err := c.doRequest(ctx, "PUT", DashboardGroupAPIURL+"/"+id, nil, bytes.NewReader(payload))
105-
if resp != nil {
106-
defer resp.Body.Close()
107-
}
10895
if err != nil {
10996
return nil, err
11097
}
98+
defer resp.Body.Close()
11199

112-
if resp.StatusCode != http.StatusOK {
113-
message, _ := ioutil.ReadAll(resp.Body)
114-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
100+
if err = newResponseError(resp, http.StatusOK); err != nil {
101+
return nil, err
115102
}
116103

117104
finalDashboardGroup := &dashboard_group.DashboardGroup{}
@@ -130,16 +117,13 @@ func (c *Client) SearchDashboardGroups(ctx context.Context, limit int, name stri
130117
params.Add("offset", strconv.Itoa(offset))
131118

132119
resp, err := c.doRequest(ctx, "GET", DashboardGroupAPIURL, params, nil)
133-
if resp != nil {
134-
defer resp.Body.Close()
135-
}
136120
if err != nil {
137121
return nil, err
138122
}
123+
defer resp.Body.Close()
139124

140-
if resp.StatusCode != http.StatusOK {
141-
message, _ := ioutil.ReadAll(resp.Body)
142-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
125+
if err = newResponseError(resp, http.StatusOK); err != nil {
126+
return nil, err
143127
}
144128

145129
finalDashboardGroups := &dashboard_group.SearchResult{}

‎datalink.go

+17-31
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -25,16 +24,13 @@ func (c *Client) CreateDataLink(ctx context.Context, dataLinkRequest *datalink.C
2524
}
2625

2726
resp, err := c.doRequest(ctx, "POST", DataLinkAPIURL, nil, bytes.NewReader(payload))
28-
if resp != nil {
29-
defer resp.Body.Close()
30-
}
3127
if err != nil {
3228
return nil, err
3329
}
30+
defer resp.Body.Close()
3431

35-
if resp.StatusCode != http.StatusOK {
36-
message, _ := ioutil.ReadAll(resp.Body)
37-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
32+
if err = newResponseError(resp, http.StatusOK); err != nil {
33+
return nil, err
3834
}
3935

4036
finalDataLink := &datalink.DataLink{}
@@ -48,19 +44,17 @@ func (c *Client) CreateDataLink(ctx context.Context, dataLinkRequest *datalink.C
4844
// DeleteDataLink deletes a data link.
4945
func (c *Client) DeleteDataLink(ctx context.Context, id string) error {
5046
resp, err := c.doRequest(ctx, "DELETE", DataLinkAPIURL+"/"+id, nil, nil)
51-
if resp != nil {
52-
defer resp.Body.Close()
53-
}
5447
if err != nil {
5548
return err
5649
}
50+
defer resp.Body.Close()
5751

5852
// The API returns a 200 here, which I think is a mistake so covering for
5953
// future changes.
60-
if resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusOK {
61-
message, _ := ioutil.ReadAll(resp.Body)
62-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
54+
if err = newResponseError(resp, http.StatusNoContent, http.StatusOK); err != nil {
55+
return err
6356
}
57+
6458
_, _ = io.Copy(ioutil.Discard, resp.Body)
6559

6660
return nil
@@ -69,16 +63,13 @@ func (c *Client) DeleteDataLink(ctx context.Context, id string) error {
6963
// GetDataLink gets a data link.
7064
func (c *Client) GetDataLink(ctx context.Context, id string) (*datalink.DataLink, error) {
7165
resp, err := c.doRequest(ctx, "GET", DataLinkAPIURL+"/"+id, nil, nil)
72-
if resp != nil {
73-
defer resp.Body.Close()
74-
}
7566
if err != nil {
7667
return nil, err
7768
}
69+
defer resp.Body.Close()
7870

79-
if resp.StatusCode != http.StatusOK {
80-
message, _ := ioutil.ReadAll(resp.Body)
81-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
71+
if err = newResponseError(resp, http.StatusOK); err != nil {
72+
return nil, err
8273
}
8374

8475
finalDataLink := &datalink.DataLink{}
@@ -98,16 +89,14 @@ func (c *Client) UpdateDataLink(ctx context.Context, id string, dataLinkRequest
9889

9990
encodedName := url.PathEscape(id)
10091
resp, err := c.doRequest(ctx, "PUT", DataLinkAPIURL+"/"+encodedName, nil, bytes.NewReader(payload))
101-
if resp != nil {
102-
defer resp.Body.Close()
103-
}
92+
10493
if err != nil {
10594
return nil, err
10695
}
96+
defer resp.Body.Close()
10797

108-
if resp.StatusCode != http.StatusOK {
109-
message, _ := ioutil.ReadAll(resp.Body)
110-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
98+
if err = newResponseError(resp, http.StatusOK); err != nil {
99+
return nil, err
111100
}
112101

113102
finalDataLink := &datalink.DataLink{}
@@ -126,16 +115,13 @@ func (c *Client) SearchDataLinks(ctx context.Context, limit int, context string,
126115
params.Add("offset", strconv.Itoa(offset))
127116

128117
resp, err := c.doRequest(ctx, "GET", DataLinkAPIURL, params, nil)
129-
if resp != nil {
130-
defer resp.Body.Close()
131-
}
132118
if err != nil {
133119
return nil, err
134120
}
121+
defer resp.Body.Close()
135122

136-
if resp.StatusCode != http.StatusOK {
137-
message, _ := ioutil.ReadAll(resp.Body)
138-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
123+
if err = newResponseError(resp, http.StatusOK); err != nil {
124+
return nil, err
139125
}
140126

141127
finalDataLinks := &datalink.SearchResults{}

‎detector.go

+30-61
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -25,16 +24,13 @@ func (c *Client) CreateDetector(ctx context.Context, detectorRequest *detector.C
2524
}
2625

2726
resp, err := c.doRequest(ctx, "POST", DetectorAPIURL, nil, bytes.NewReader(payload))
28-
if resp != nil {
29-
defer resp.Body.Close()
30-
}
3127
if err != nil {
3228
return nil, err
3329
}
30+
defer resp.Body.Close()
3431

35-
if resp.StatusCode != http.StatusOK {
36-
message, _ := ioutil.ReadAll(resp.Body)
37-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
32+
if err = newResponseError(resp, http.StatusOK); err != nil {
33+
return nil, err
3834
}
3935

4036
finalDetector := &detector.Detector{}
@@ -48,16 +44,13 @@ func (c *Client) CreateDetector(ctx context.Context, detectorRequest *detector.C
4844
// DeleteDetector deletes a detector.
4945
func (c *Client) DeleteDetector(ctx context.Context, id string) error {
5046
resp, err := c.doRequest(ctx, "DELETE", DetectorAPIURL+"/"+id, nil, nil)
51-
if resp != nil {
52-
defer resp.Body.Close()
53-
}
5447
if err != nil {
5548
return err
5649
}
50+
defer resp.Body.Close()
5751

58-
if resp.StatusCode != http.StatusNoContent {
59-
message, _ := ioutil.ReadAll(resp.Body)
60-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
52+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
53+
return err
6154
}
6255
_, _ = io.Copy(ioutil.Discard, resp.Body)
6356

@@ -72,16 +65,13 @@ func (c *Client) DisableDetector(ctx context.Context, id string, labels []string
7265
}
7366

7467
resp, err := c.doRequest(ctx, "PUT", DetectorAPIURL+"/"+id+"/disable", nil, bytes.NewReader(payload))
75-
if resp != nil {
76-
defer resp.Body.Close()
77-
}
7868
if err != nil {
7969
return err
8070
}
71+
defer resp.Body.Close()
8172

82-
if resp.StatusCode != http.StatusNoContent {
83-
message, _ := ioutil.ReadAll(resp.Body)
84-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
73+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
74+
return err
8575
}
8676
_, _ = io.Copy(ioutil.Discard, resp.Body)
8777

@@ -96,16 +86,13 @@ func (c *Client) EnableDetector(ctx context.Context, id string, labels []string)
9686
}
9787

9888
resp, err := c.doRequest(ctx, "PUT", DetectorAPIURL+"/"+id+"/enable", nil, bytes.NewReader(payload))
99-
if resp != nil {
100-
defer resp.Body.Close()
101-
}
10289
if err != nil {
10390
return err
10491
}
92+
defer resp.Body.Close()
10593

106-
if resp.StatusCode != http.StatusNoContent {
107-
message, _ := ioutil.ReadAll(resp.Body)
108-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
94+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
95+
return err
10996
}
11097
_, _ = io.Copy(ioutil.Discard, resp.Body)
11198

@@ -115,16 +102,13 @@ func (c *Client) EnableDetector(ctx context.Context, id string, labels []string)
115102
// GetDetector gets a detector.
116103
func (c *Client) GetDetector(ctx context.Context, id string) (*detector.Detector, error) {
117104
resp, err := c.doRequest(ctx, "GET", DetectorAPIURL+"/"+id, nil, nil)
118-
if resp != nil {
119-
defer resp.Body.Close()
120-
}
121105
if err != nil {
122106
return nil, err
123107
}
108+
defer resp.Body.Close()
124109

125-
if resp.StatusCode != http.StatusOK {
126-
message, _ := ioutil.ReadAll(resp.Body)
127-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
110+
if err = newResponseError(resp, http.StatusOK); err != nil {
111+
return nil, err
128112
}
129113

130114
finalDetector := &detector.Detector{}
@@ -143,16 +127,13 @@ func (c *Client) UpdateDetector(ctx context.Context, id string, detectorRequest
143127
}
144128

145129
resp, err := c.doRequest(ctx, "PUT", DetectorAPIURL+"/"+id, nil, bytes.NewReader(payload))
146-
if resp != nil {
147-
defer resp.Body.Close()
148-
}
149130
if err != nil {
150131
return nil, err
151132
}
133+
defer resp.Body.Close()
152134

153-
if resp.StatusCode != http.StatusOK {
154-
message, _ := ioutil.ReadAll(resp.Body)
155-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
135+
if err = newResponseError(resp, http.StatusOK); err != nil {
136+
return nil, err
156137
}
157138

158139
finalDetector := &detector.Detector{}
@@ -174,16 +155,13 @@ func (c *Client) SearchDetectors(ctx context.Context, limit int, name string, of
174155
}
175156

176157
resp, err := c.doRequest(ctx, "GET", DetectorAPIURL, params, nil)
177-
if resp != nil {
178-
defer resp.Body.Close()
179-
}
180158
if err != nil {
181159
return nil, err
182160
}
161+
defer resp.Body.Close()
183162

184-
if resp.StatusCode != http.StatusOK {
185-
message, _ := ioutil.ReadAll(resp.Body)
186-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
163+
if err = newResponseError(resp, http.StatusOK); err != nil {
164+
return nil, err
187165
}
188166

189167
finalDetectors := &detector.SearchResults{}
@@ -202,16 +180,13 @@ func (c *Client) GetDetectorEvents(ctx context.Context, id string, from int, to
202180
params.Add("offset", strconv.Itoa(offset))
203181
params.Add("limit", strconv.Itoa(limit))
204182
resp, err := c.doRequest(ctx, "GET", DetectorAPIURL+"/"+id+"/events", params, nil)
205-
if resp != nil {
206-
defer resp.Body.Close()
207-
}
208183
if err != nil {
209184
return nil, err
210185
}
186+
defer resp.Body.Close()
211187

212-
if resp.StatusCode != http.StatusOK {
213-
message, _ := ioutil.ReadAll(resp.Body)
214-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
188+
if err = newResponseError(resp, http.StatusOK); err != nil {
189+
return nil, err
215190
}
216191

217192
var events []*detector.Event
@@ -228,16 +203,13 @@ func (c *Client) GetDetectorIncidents(ctx context.Context, id string, offset int
228203
params.Add("offset", strconv.Itoa(offset))
229204
params.Add("limit", strconv.Itoa(limit))
230205
resp, err := c.doRequest(ctx, "GET", DetectorAPIURL+"/"+id+"/incidents", params, nil)
231-
if resp != nil {
232-
defer resp.Body.Close()
233-
}
234206
if err != nil {
235207
return nil, err
236208
}
209+
defer resp.Body.Close()
237210

238-
if resp.StatusCode != http.StatusOK {
239-
message, _ := ioutil.ReadAll(resp.Body)
240-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
211+
if err = newResponseError(resp, http.StatusOK); err != nil {
212+
return nil, err
241213
}
242214

243215
var incidents []*detector.Incident
@@ -256,16 +228,13 @@ func (c *Client) ValidateDetector(ctx context.Context, detectorRequest *detector
256228
}
257229

258230
resp, err := c.doRequest(ctx, "POST", DetectorAPIURL+"/validate", nil, bytes.NewReader(payload))
259-
if resp != nil {
260-
defer resp.Body.Close()
261-
}
262231
if err != nil {
263232
return err
264233
}
234+
defer resp.Body.Close()
265235

266-
if resp.StatusCode != http.StatusNoContent {
267-
message, _ := ioutil.ReadAll(resp.Body)
268-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
236+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
237+
return err
269238
}
270239
_, _ = io.Copy(ioutil.Discard, resp.Body)
271240

‎errors.go

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package signalfx
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"slices"
9+
)
10+
11+
// ResponseError captures the error details
12+
// and allows for it to be inspected by external libraries.
13+
type ResponseError struct {
14+
code int
15+
route string
16+
details string
17+
}
18+
19+
var _ error = (*ResponseError)(nil)
20+
21+
func newResponseError(resp *http.Response, target int, targets ...int) error {
22+
if resp == nil {
23+
return nil
24+
}
25+
26+
if slices.Contains(append([]int{target}, targets...), resp.StatusCode) {
27+
return nil
28+
}
29+
30+
details, _ := io.ReadAll(resp.Body)
31+
32+
return &ResponseError{
33+
code: resp.StatusCode,
34+
route: resp.Request.URL.Path,
35+
details: string(details),
36+
}
37+
}
38+
39+
// AsResponseError is a convenience function to check the error
40+
// to see if it contains an `ResponseError` and returns the value with true.
41+
// If the error was initially joined using [errors.Join], it will check each error
42+
// within the list and return the first matching error.
43+
func AsResponseError(err error) (*ResponseError, bool) {
44+
// When `errors.Join` is called, it returns an error that
45+
// matches the provided interface.
46+
if joined, ok := err.(interface{ Unwrap() []error }); ok {
47+
for _, err := range joined.Unwrap() {
48+
if re, ok := AsResponseError(err); ok {
49+
return re, ok
50+
}
51+
}
52+
return nil, false
53+
}
54+
55+
for err != nil {
56+
if re, ok := err.(*ResponseError); ok {
57+
return re, true
58+
}
59+
// In case the error is wrapped using `fmt.Errorf`
60+
// this will also account for that.
61+
err = errors.Unwrap(err)
62+
}
63+
return nil, false
64+
}
65+
66+
func (re *ResponseError) Error() string {
67+
return fmt.Sprintf("route %q had issues with status code %d", re.route, re.code)
68+
}
69+
70+
func (re *ResponseError) Code() int {
71+
return re.code
72+
}
73+
74+
func (re *ResponseError) Route() string {
75+
return re.route
76+
}
77+
78+
func (re *ResponseError) Details() string {
79+
return re.details
80+
}

‎errors_test.go

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package signalfx
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"net/url"
9+
"strings"
10+
"testing"
11+
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
func TestRequestError(t *testing.T) {
16+
t.Parallel()
17+
18+
for _, tc := range []struct {
19+
name string
20+
re *ResponseError
21+
err string
22+
}{
23+
{
24+
name: "simple request error",
25+
re: &ResponseError{
26+
code: 404,
27+
route: "/internal/heathz",
28+
details: "failed due to overworked",
29+
},
30+
err: "route \"/internal/heathz\" had issues with status code 404",
31+
},
32+
{
33+
name: "missed details",
34+
re: &ResponseError{
35+
code: 404,
36+
route: "/internal/heathz",
37+
},
38+
err: "route \"/internal/heathz\" had issues with status code 404",
39+
},
40+
{
41+
name: "missed code",
42+
re: &ResponseError{
43+
route: "/internal/heathz",
44+
},
45+
err: "route \"/internal/heathz\" had issues with status code 0",
46+
},
47+
{
48+
name: "missed all info",
49+
re: &ResponseError{},
50+
err: "route \"\" had issues with status code 0",
51+
},
52+
} {
53+
tc := tc
54+
t.Run(tc.name, func(t *testing.T) {
55+
t.Parallel()
56+
57+
assert.EqualError(t, tc.re, tc.err, "Must match the expected error string")
58+
})
59+
}
60+
}
61+
62+
func TestNewRequestError(t *testing.T) {
63+
t.Parallel()
64+
65+
for _, tc := range []struct {
66+
name string
67+
resp *http.Response
68+
expect error
69+
}{
70+
{
71+
name: "no response",
72+
resp: nil,
73+
expect: nil,
74+
},
75+
{
76+
name: "successful response",
77+
resp: &http.Response{
78+
StatusCode: http.StatusOK,
79+
Request: &http.Request{
80+
URL: &url.URL{Host: "localhost", Path: "/internal/heathz"},
81+
},
82+
Body: io.NopCloser(strings.NewReader("successs")),
83+
},
84+
expect: nil,
85+
},
86+
{
87+
name: "failed response",
88+
resp: &http.Response{
89+
StatusCode: http.StatusInternalServerError,
90+
Request: &http.Request{
91+
URL: &url.URL{Host: "localhost", Path: "/internal/heathz"},
92+
},
93+
Body: io.NopCloser(strings.NewReader("issue trying to connect")),
94+
},
95+
expect: &ResponseError{
96+
code: http.StatusInternalServerError,
97+
route: "/internal/heathz",
98+
details: "issue trying to connect",
99+
},
100+
},
101+
} {
102+
tc := tc
103+
t.Run(tc.name, func(t *testing.T) {
104+
t.Parallel()
105+
106+
assert.Equal(t, tc.expect, newResponseError(tc.resp, http.StatusOK), "Must match the exected value")
107+
})
108+
}
109+
}
110+
111+
func TestIsRequestError(t *testing.T) {
112+
t.Parallel()
113+
114+
for _, tc := range []struct {
115+
name string
116+
err error
117+
expected bool
118+
}{
119+
{
120+
name: "no error provided",
121+
err: nil,
122+
expected: false,
123+
},
124+
{
125+
name: "not a request error",
126+
err: errors.New("failed"),
127+
expected: false,
128+
},
129+
{
130+
name: "is a request error",
131+
err: &ResponseError{},
132+
expected: true,
133+
},
134+
{
135+
name: "joined errors",
136+
err: errors.Join(errors.New("boom"), &ResponseError{}),
137+
expected: true,
138+
},
139+
{
140+
name: "fmt error",
141+
err: fmt.Errorf("check permissions: %w", &ResponseError{}),
142+
expected: true,
143+
},
144+
} {
145+
tc := tc
146+
t.Run(tc.name, func(t *testing.T) {
147+
t.Parallel()
148+
149+
_, ok := AsResponseError(tc.err)
150+
assert.Equal(t, tc.expected, ok, "Must match the expected value")
151+
})
152+
}
153+
}
154+
155+
func TestRequestErrorMethods(t *testing.T) {
156+
t.Parallel()
157+
158+
re := &ResponseError{code: http.StatusOK, route: "/heathz", details: "service alive"}
159+
160+
assert.Equal(t, 200, re.Code(), "Must match the expected code")
161+
assert.Equal(t, "/heathz", re.Route(), "Must match the expected route")
162+
assert.Equal(t, "service alive", re.Details(), "Must match the expected details")
163+
}

‎gcp_integration.go

+12-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -20,16 +19,13 @@ func (c *Client) CreateGCPIntegration(ctx context.Context, gcpi *integration.GCP
2019
}
2120

2221
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
23-
if resp != nil {
24-
defer resp.Body.Close()
25-
}
2622
if err != nil {
2723
return nil, err
2824
}
25+
defer resp.Body.Close()
2926

30-
if resp.StatusCode != http.StatusOK {
31-
message, _ := ioutil.ReadAll(resp.Body)
32-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
27+
if err = newResponseError(resp, http.StatusOK); err != nil {
28+
return nil, err
3329
}
3430

3531
finalIntegration := integration.GCPIntegration{}
@@ -43,16 +39,13 @@ func (c *Client) CreateGCPIntegration(ctx context.Context, gcpi *integration.GCP
4339
// GetGCPIntegration retrieves a GCP integration.
4440
func (c *Client) GetGCPIntegration(ctx context.Context, id string) (*integration.GCPIntegration, error) {
4541
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
46-
if resp != nil {
47-
defer resp.Body.Close()
48-
}
4942
if err != nil {
5043
return nil, err
5144
}
45+
defer resp.Body.Close()
5246

53-
if resp.StatusCode != http.StatusOK {
54-
message, _ := ioutil.ReadAll(resp.Body)
55-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
47+
if err = newResponseError(resp, http.StatusOK); err != nil {
48+
return nil, err
5649
}
5750

5851
finalIntegration := integration.GCPIntegration{}
@@ -71,16 +64,13 @@ func (c *Client) UpdateGCPIntegration(ctx context.Context, id string, gcpi *inte
7164
}
7265

7366
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
7767
if err != nil {
7868
return nil, err
7969
}
70+
defer resp.Body.Close()
8071

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
72+
if err = newResponseError(resp, http.StatusOK); err != nil {
73+
return nil, err
8474
}
8575

8676
finalIntegration := integration.GCPIntegration{}
@@ -94,16 +84,13 @@ func (c *Client) UpdateGCPIntegration(ctx context.Context, id string, gcpi *inte
9484
// DeleteGCPIntegration deletes a GCP integration.
9585
func (c *Client) DeleteGCPIntegration(ctx context.Context, id string) error {
9686
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10087
if err != nil {
10188
return err
10289
}
90+
defer resp.Body.Close()
10391

104-
if resp.StatusCode != http.StatusNoContent {
105-
message, _ := ioutil.ReadAll(resp.Body)
106-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
92+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
93+
return err
10794
}
10895
_, _ = io.Copy(ioutil.Discard, resp.Body)
10996

‎incident.go

+7-17
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package signalfx
33
import (
44
"context"
55
"encoding/json"
6-
"fmt"
76
"io"
87
"io/ioutil"
98
"net/http"
@@ -19,16 +18,13 @@ const IncidentAPIURL = "/v2/incident"
1918
// Get incident with the given id
2019
func (c *Client) GetIncident(ctx context.Context, id string) (*detector.Incident, error) {
2120
resp, err := c.doRequest(ctx, "GET", IncidentAPIURL+"/"+id, nil, nil)
22-
if resp != nil {
23-
defer resp.Body.Close()
24-
}
2521
if err != nil {
2622
return nil, err
2723
}
24+
defer resp.Body.Close()
2825

29-
if resp.StatusCode != http.StatusOK {
30-
message, _ := ioutil.ReadAll(resp.Body)
31-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
26+
if err = newResponseError(resp, http.StatusOK); err != nil {
27+
return nil, err
3228
}
3329

3430
finalIncident := &detector.Incident{}
@@ -47,20 +43,14 @@ func (c *Client) GetIncidents(ctx context.Context, includeResolved bool, limit i
4743
params.Add("query", query)
4844
params.Add("offset", strconv.Itoa(offset))
4945
resp, err := c.doRequest(ctx, "GET", IncidentAPIURL, params, nil)
50-
if resp != nil {
51-
defer resp.Body.Close()
52-
}
53-
if resp.StatusCode != http.StatusOK {
54-
body, err := io.ReadAll(resp.Body)
55-
if err != nil {
56-
return nil, err
57-
}
58-
return nil, fmt.Errorf(string(body))
59-
}
6046
if err != nil {
6147
return nil, err
6248
}
6349

50+
if err = newResponseError(resp, http.StatusOK); err != nil {
51+
return nil, err
52+
}
53+
6454
var incidents []*detector.Incident
6555
err = json.NewDecoder(resp.Body).Decode(&incidents)
6656
_, _ = io.Copy(ioutil.Discard, resp.Body)

‎integration.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"bytes"
1111
"context"
1212
"encoding/json"
13-
"fmt"
1413
"io"
1514
"io/ioutil"
1615
"net/http"
@@ -69,9 +68,8 @@ func (c *Client) doIntegrationRequest(ctx context.Context, url string, method st
6968
return err
7069
}
7170

72-
if resp.StatusCode != status {
73-
message, _ := ioutil.ReadAll(resp.Body)
74-
return fmt.Errorf("unexpected status code: %d: %s", resp.StatusCode, message)
71+
if err = newResponseError(resp, status); err != nil {
72+
return err
7573
}
7674

7775
if out != nil {

‎jira_integration.go

+12-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -20,16 +19,13 @@ func (c *Client) CreateJiraIntegration(ctx context.Context, ji *integration.Jira
2019
}
2120

2221
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
23-
if resp != nil {
24-
defer resp.Body.Close()
25-
}
2622
if err != nil {
2723
return nil, err
2824
}
25+
defer resp.Body.Close()
2926

30-
if resp.StatusCode != http.StatusOK {
31-
message, _ := ioutil.ReadAll(resp.Body)
32-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
27+
if err = newResponseError(resp, http.StatusOK); err != nil {
28+
return nil, err
3329
}
3430

3531
finalIntegration := integration.JiraIntegration{}
@@ -43,16 +39,13 @@ func (c *Client) CreateJiraIntegration(ctx context.Context, ji *integration.Jira
4339
// GetJiraIntegration retrieves an Jira integration.
4440
func (c *Client) GetJiraIntegration(ctx context.Context, id string) (*integration.JiraIntegration, error) {
4541
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
46-
if resp != nil {
47-
defer resp.Body.Close()
48-
}
4942
if err != nil {
5043
return nil, err
5144
}
45+
defer resp.Body.Close()
5246

53-
if resp.StatusCode != http.StatusOK {
54-
message, _ := ioutil.ReadAll(resp.Body)
55-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
47+
if err = newResponseError(resp, http.StatusOK); err != nil {
48+
return nil, err
5649
}
5750

5851
finalIntegration := integration.JiraIntegration{}
@@ -71,16 +64,13 @@ func (c *Client) UpdateJiraIntegration(ctx context.Context, id string, ji *integ
7164
}
7265

7366
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
7767
if err != nil {
7868
return nil, err
7969
}
70+
defer resp.Body.Close()
8071

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
72+
if err = newResponseError(resp, http.StatusOK); err != nil {
73+
return nil, err
8474
}
8575

8676
finalIntegration := integration.JiraIntegration{}
@@ -94,16 +84,13 @@ func (c *Client) UpdateJiraIntegration(ctx context.Context, id string, ji *integ
9484
// DeleteJiraIntegration deletes an Jira integration.
9585
func (c *Client) DeleteJiraIntegration(ctx context.Context, id string) error {
9686
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10087
if err != nil {
10188
return err
10289
}
90+
defer resp.Body.Close()
10391

104-
if resp.StatusCode != http.StatusNoContent {
105-
message, _ := ioutil.ReadAll(resp.Body)
106-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
92+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
93+
return err
10794
}
10895
_, _ = io.Copy(ioutil.Discard, resp.Body)
10996

‎metric_ruleset.go

+14-30
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -18,16 +17,13 @@ const MetricRulesetApiURL = "/v2/metricruleset"
1817
// GetMetricRuleset gets a metric ruleset.
1918
func (c *Client) GetMetricRuleset(ctx context.Context, id string) (*metric_ruleset.GetMetricRulesetResponse, error) {
2019
resp, err := c.doRequest(ctx, http.MethodGet, MetricRulesetApiURL+"/"+id, nil, nil)
21-
if resp != nil {
22-
defer resp.Body.Close()
23-
}
2420
if err != nil {
2521
return nil, err
2622
}
23+
defer resp.Body.Close()
2724

28-
if resp.StatusCode != http.StatusOK {
29-
message, _ := ioutil.ReadAll(resp.Body)
30-
return nil, fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
25+
if err = newResponseError(resp, http.StatusOK); err != nil {
26+
return nil, err
3127
}
3228

3329
metricRuleset := &metric_ruleset.GetMetricRulesetResponse{}
@@ -53,9 +49,8 @@ func (c *Client) CreateMetricRuleset(ctx context.Context, metricRuleset *metric_
5349
return nil, err
5450
}
5551

56-
if resp.StatusCode != http.StatusOK {
57-
message, _ := ioutil.ReadAll(resp.Body)
58-
return nil, fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
52+
if err = newResponseError(resp, http.StatusOK); err != nil {
53+
return nil, err
5954
}
6055

6156
createdMetricRuleset := &metric_ruleset.CreateMetricRulesetResponse{}
@@ -73,17 +68,13 @@ func (c *Client) UpdateMetricRuleset(ctx context.Context, id string, metricRules
7368
}
7469

7570
resp, err := c.doRequest(ctx, http.MethodPut, MetricRulesetApiURL+"/"+id, nil, bytes.NewReader(payload))
76-
if resp != nil {
77-
defer resp.Body.Close()
78-
}
79-
8071
if err != nil {
8172
return nil, err
8273
}
74+
defer resp.Body.Close()
8375

84-
if resp.StatusCode != http.StatusOK {
85-
message, _ := ioutil.ReadAll(resp.Body)
86-
return nil, fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
76+
if err = newResponseError(resp, http.StatusOK); err != nil {
77+
return nil, err
8778
}
8879

8980
updatedMetricRuleset := &metric_ruleset.UpdateMetricRulesetResponse{}
@@ -96,17 +87,13 @@ func (c *Client) UpdateMetricRuleset(ctx context.Context, id string, metricRules
9687
// DeleteMetricRuleset deletes a metric ruleset.
9788
func (c *Client) DeleteMetricRuleset(ctx context.Context, id string) error {
9889
resp, err := c.doRequest(ctx, http.MethodDelete, MetricRulesetApiURL+"/"+id, nil, nil)
99-
if resp != nil {
100-
defer resp.Body.Close()
101-
}
102-
10390
if err != nil {
10491
return err
10592
}
93+
defer resp.Body.Close()
10694

107-
if resp.StatusCode != http.StatusNoContent {
108-
message, _ := ioutil.ReadAll(resp.Body)
109-
return fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
95+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
96+
return err
11097
}
11198

11299
io.Copy(ioutil.Discard, resp.Body)
@@ -121,16 +108,13 @@ func (c *Client) GenerateAggregationMetricName(ctx context.Context, generateAggr
121108
}
122109

123110
resp, err := c.doRequest(ctx, http.MethodPost, MetricRulesetApiURL+"/generateAggregationMetricName", nil, bytes.NewReader(payload))
124-
if resp != nil {
125-
defer resp.Body.Close()
126-
}
127111
if err != nil {
128112
return "", err
129113
}
114+
defer resp.Body.Close()
130115

131-
if resp.StatusCode != http.StatusOK {
132-
message, _ := ioutil.ReadAll(resp.Body)
133-
return "", fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
116+
if err = newResponseError(resp, http.StatusOK); err != nil {
117+
return "", err
134118
}
135119

136120
respBody, err := ioutil.ReadAll(resp.Body)

‎metrics_metadata.go

+36-73
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -29,16 +28,13 @@ const TagAPIURL = "/v2/tag"
2928
// GetDimension gets a dimension.
3029
func (c *Client) GetDimension(ctx context.Context, key string, value string) (*metrics_metadata.Dimension, error) {
3130
resp, err := c.doRequest(ctx, "GET", DimensionAPIURL+"/"+key+"/"+value, nil, nil)
32-
if resp != nil {
33-
defer resp.Body.Close()
34-
}
3531
if err != nil {
3632
return nil, err
3733
}
34+
defer resp.Body.Close()
3835

39-
if resp.StatusCode != http.StatusOK {
40-
message, _ := ioutil.ReadAll(resp.Body)
41-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
36+
if err = newResponseError(resp, http.StatusOK); err != nil {
37+
return nil, err
4238
}
4339

4440
finalDimension := &metrics_metadata.Dimension{}
@@ -56,16 +52,13 @@ func (c *Client) UpdateDimension(ctx context.Context, key string, value string,
5652
}
5753

5854
resp, err := c.doRequest(ctx, "PUT", DimensionAPIURL+"/"+key+"/"+value, nil, bytes.NewReader(payload))
59-
if resp != nil {
60-
defer resp.Body.Close()
61-
}
6255
if err != nil {
6356
return nil, err
6457
}
58+
defer resp.Body.Close()
6559

66-
if resp.StatusCode != http.StatusOK {
67-
message, _ := ioutil.ReadAll(resp.Body)
68-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
60+
if err = newResponseError(resp, http.StatusOK); err != nil {
61+
return nil, err
6962
}
7063

7164
finalDimension := &metrics_metadata.Dimension{}
@@ -87,16 +80,13 @@ func (c *Client) SearchDimension(ctx context.Context, query string, orderBy stri
8780
params.Add("offset", strconv.Itoa(offset))
8881

8982
resp, err := c.doRequest(ctx, "GET", DimensionAPIURL, params, nil)
90-
if resp != nil {
91-
defer resp.Body.Close()
92-
}
9383
if err != nil {
9484
return nil, err
9585
}
86+
defer resp.Body.Close()
9687

97-
if resp.StatusCode != http.StatusOK {
98-
message, _ := ioutil.ReadAll(resp.Body)
99-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
88+
if err = newResponseError(resp, http.StatusOK); err != nil {
89+
return nil, err
10090
}
10191

10292
finalDimensions := &metrics_metadata.DimensionQueryResponseModel{}
@@ -118,16 +108,13 @@ func (c *Client) SearchMetric(ctx context.Context, query string, orderBy string,
118108
params.Add("offset", strconv.Itoa(offset))
119109

120110
resp, err := c.doRequest(ctx, "GET", MetricAPIURL, params, nil)
121-
if resp != nil {
122-
defer resp.Body.Close()
123-
}
124111
if err != nil {
125112
return nil, err
126113
}
114+
defer resp.Body.Close()
127115

128-
if resp.StatusCode != http.StatusOK {
129-
message, _ := ioutil.ReadAll(resp.Body)
130-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
116+
if err = newResponseError(resp, http.StatusOK); err != nil {
117+
return nil, err
131118
}
132119

133120
finalMetrics := &metrics_metadata.RetrieveMetricMetadataResponseModel{}
@@ -141,16 +128,13 @@ func (c *Client) SearchMetric(ctx context.Context, query string, orderBy string,
141128
// GetMetric retrieves a single metric by name.
142129
func (c *Client) GetMetric(ctx context.Context, name string) (*metrics_metadata.Metric, error) {
143130
resp, err := c.doRequest(ctx, "GET", MetricAPIURL+"/"+name, nil, nil)
144-
if resp != nil {
145-
defer resp.Body.Close()
146-
}
147131
if err != nil {
148132
return nil, err
149133
}
134+
defer resp.Body.Close()
150135

151-
if resp.StatusCode != http.StatusOK {
152-
message, _ := ioutil.ReadAll(resp.Body)
153-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
136+
if err = newResponseError(resp, http.StatusOK); err != nil {
137+
return nil, err
154138
}
155139

156140
finalMetric := &metrics_metadata.Metric{}
@@ -169,16 +153,13 @@ func (c *Client) CreateUpdateMetric(ctx context.Context, name string, cumr *metr
169153
}
170154

171155
resp, err := c.doRequest(ctx, "PUT", MetricAPIURL+"/"+name, nil, bytes.NewReader(payload))
172-
if resp != nil {
173-
defer resp.Body.Close()
174-
}
175156
if err != nil {
176157
return nil, err
177158
}
159+
defer resp.Body.Close()
178160

179-
if resp.StatusCode != http.StatusOK {
180-
message, _ := ioutil.ReadAll(resp.Body)
181-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
161+
if err = newResponseError(resp, http.StatusOK); err != nil {
162+
return nil, err
182163
}
183164

184165
finalMetric := &metrics_metadata.Metric{}
@@ -192,16 +173,13 @@ func (c *Client) CreateUpdateMetric(ctx context.Context, name string, cumr *metr
192173
// GetMetricTimeSeries retrieves a metric time series by id.
193174
func (c *Client) GetMetricTimeSeries(ctx context.Context, id string) (*metrics_metadata.MetricTimeSeries, error) {
194175
resp, err := c.doRequest(ctx, "GET", MetricTimeSeriesAPIURL+"/"+id, nil, nil)
195-
if resp != nil {
196-
defer resp.Body.Close()
197-
}
198176
if err != nil {
199177
return nil, err
200178
}
179+
defer resp.Body.Close()
201180

202-
if resp.StatusCode != http.StatusOK {
203-
message, _ := ioutil.ReadAll(resp.Body)
204-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
181+
if err = newResponseError(resp, http.StatusOK); err != nil {
182+
return nil, err
205183
}
206184

207185
finalMetricTimeSeries := &metrics_metadata.MetricTimeSeries{}
@@ -223,16 +201,13 @@ func (c *Client) SearchMetricTimeSeries(ctx context.Context, query string, order
223201
params.Add("offset", strconv.Itoa(offset))
224202

225203
resp, err := c.doRequest(ctx, "GET", MetricTimeSeriesAPIURL, params, nil)
226-
if resp != nil {
227-
defer resp.Body.Close()
228-
}
229204
if err != nil {
230205
return nil, err
231206
}
207+
defer resp.Body.Close()
232208

233-
if resp.StatusCode != http.StatusOK {
234-
message, _ := ioutil.ReadAll(resp.Body)
235-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
209+
if err = newResponseError(resp, http.StatusOK); err != nil {
210+
return nil, err
236211
}
237212

238213
finalMTS := &metrics_metadata.MetricTimeSeriesRetrieveResponseModel{}
@@ -254,16 +229,13 @@ func (c *Client) SearchTag(ctx context.Context, query string, orderBy string, li
254229
params.Add("offset", strconv.Itoa(offset))
255230

256231
resp, err := c.doRequest(ctx, "GET", TagAPIURL, params, nil)
257-
if resp != nil {
258-
defer resp.Body.Close()
259-
}
260232
if err != nil {
261233
return nil, err
262234
}
235+
defer resp.Body.Close()
263236

264-
if resp.StatusCode != http.StatusOK {
265-
message, _ := ioutil.ReadAll(resp.Body)
266-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
237+
if err = newResponseError(resp, http.StatusOK); err != nil {
238+
return nil, err
267239
}
268240

269241
finalTags := &metrics_metadata.TagRetrieveResponseModel{}
@@ -277,16 +249,13 @@ func (c *Client) SearchTag(ctx context.Context, query string, orderBy string, li
277249
// GetTag gets a tag by name
278250
func (c *Client) GetTag(ctx context.Context, name string) (*metrics_metadata.Tag, error) {
279251
resp, err := c.doRequest(ctx, "GET", TagAPIURL+"/"+name, nil, nil)
280-
if resp != nil {
281-
defer resp.Body.Close()
282-
}
283252
if err != nil {
284253
return nil, err
285254
}
255+
defer resp.Body.Close()
286256

287-
if resp.StatusCode != http.StatusOK {
288-
message, _ := ioutil.ReadAll(resp.Body)
289-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
257+
if err = newResponseError(resp, http.StatusOK); err != nil {
258+
return nil, err
290259
}
291260

292261
finalTag := &metrics_metadata.Tag{}
@@ -300,16 +269,13 @@ func (c *Client) GetTag(ctx context.Context, name string) (*metrics_metadata.Tag
300269
// DeleteTag deletes a tag.
301270
func (c *Client) DeleteTag(ctx context.Context, id string) error {
302271
resp, err := c.doRequest(ctx, "DELETE", TagAPIURL+"/"+id, nil, nil)
303-
if resp != nil {
304-
defer resp.Body.Close()
305-
}
306272
if err != nil {
307273
return err
308274
}
275+
defer resp.Body.Close()
309276

310-
if resp.StatusCode != http.StatusNoContent {
311-
message, _ := ioutil.ReadAll(resp.Body)
312-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
277+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
278+
return err
313279
}
314280
_, _ = io.Copy(ioutil.Discard, resp.Body)
315281

@@ -324,16 +290,13 @@ func (c *Client) CreateUpdateTag(ctx context.Context, name string, cutr *metrics
324290
}
325291

326292
resp, err := c.doRequest(ctx, "PUT", TagAPIURL+"/"+name, nil, bytes.NewReader(payload))
327-
if resp != nil {
328-
defer resp.Body.Close()
329-
}
330293
if err != nil {
331294
return nil, err
332295
}
296+
defer resp.Body.Close()
333297

334-
if resp.StatusCode != http.StatusOK {
335-
message, _ := ioutil.ReadAll(resp.Body)
336-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
298+
if err = newResponseError(resp, http.StatusOK); err != nil {
299+
return nil, err
337300
}
338301

339302
finalTag := &metrics_metadata.Tag{}

‎opsgenie_integration.go

+13-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -20,16 +19,13 @@ func (c *Client) CreateOpsgenieIntegration(ctx context.Context, oi *integration.
2019
}
2120

2221
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
23-
if resp != nil {
24-
defer resp.Body.Close()
25-
}
2622
if err != nil {
2723
return nil, err
2824
}
25+
defer resp.Body.Close()
2926

30-
if resp.StatusCode != http.StatusOK {
31-
message, _ := ioutil.ReadAll(resp.Body)
32-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
27+
if err = newResponseError(resp, http.StatusOK); err != nil {
28+
return nil, err
3329
}
3430

3531
finalIntegration := integration.OpsgenieIntegration{}
@@ -43,16 +39,13 @@ func (c *Client) CreateOpsgenieIntegration(ctx context.Context, oi *integration.
4339
// GetOpsgenieIntegration retrieves an Opsgenie integration.
4440
func (c *Client) GetOpsgenieIntegration(ctx context.Context, id string) (*integration.OpsgenieIntegration, error) {
4541
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
46-
if resp != nil {
47-
defer resp.Body.Close()
48-
}
4942
if err != nil {
5043
return nil, err
5144
}
45+
defer resp.Body.Close()
5246

53-
if resp.StatusCode != http.StatusOK {
54-
message, _ := ioutil.ReadAll(resp.Body)
55-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
47+
if err = newResponseError(resp, http.StatusOK); err != nil {
48+
return nil, err
5649
}
5750

5851
finalIntegration := integration.OpsgenieIntegration{}
@@ -71,16 +64,13 @@ func (c *Client) UpdateOpsgenieIntegration(ctx context.Context, id string, oi *i
7164
}
7265

7366
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
7767
if err != nil {
7868
return nil, err
7969
}
70+
defer resp.Body.Close()
8071

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
72+
if err = newResponseError(resp, http.StatusOK); err != nil {
73+
return nil, err
8474
}
8575

8676
finalIntegration := integration.OpsgenieIntegration{}
@@ -94,17 +84,15 @@ func (c *Client) UpdateOpsgenieIntegration(ctx context.Context, id string, oi *i
9484
// DeleteOpsgenieIntegration deletes an Opsgenie integration.
9585
func (c *Client) DeleteOpsgenieIntegration(ctx context.Context, id string) error {
9686
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10087
if err != nil {
10188
return err
10289
}
90+
defer resp.Body.Close()
10391

104-
if resp.StatusCode != http.StatusNoContent {
105-
message, _ := ioutil.ReadAll(resp.Body)
106-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
92+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
93+
return err
10794
}
95+
10896
_, _ = io.Copy(ioutil.Discard, resp.Body)
10997

11098
return err

‎organization.go

+21-43
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -22,16 +21,13 @@ const OrganizationMembersAPIURL = "/v2/organization/members"
2221
// GetOrganization gets an organization.
2322
func (c *Client) GetOrganization(ctx context.Context, id string) (*organization.Organization, error) {
2423
resp, err := c.doRequest(ctx, "GET", OrganizationAPIURL+"/"+id, nil, nil)
25-
if resp != nil {
26-
defer resp.Body.Close()
27-
}
2824
if err != nil {
2925
return nil, err
3026
}
27+
defer resp.Body.Close()
3128

32-
if resp.StatusCode != http.StatusOK {
33-
message, _ := ioutil.ReadAll(resp.Body)
34-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
29+
if err = newResponseError(resp, http.StatusOK); err != nil {
30+
return nil, err
3531
}
3632

3733
finalOrganization := &organization.Organization{}
@@ -45,16 +41,13 @@ func (c *Client) GetOrganization(ctx context.Context, id string) (*organization.
4541
// GetMember gets a member.
4642
func (c *Client) GetMember(ctx context.Context, id string) (*organization.Member, error) {
4743
resp, err := c.doRequest(ctx, "GET", OrganizationMemberAPIURL+"/"+id, nil, nil)
48-
if resp != nil {
49-
defer resp.Body.Close()
50-
}
5144
if err != nil {
5245
return nil, err
5346
}
47+
defer resp.Body.Close()
5448

55-
if resp.StatusCode != http.StatusOK {
56-
message, _ := ioutil.ReadAll(resp.Body)
57-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
49+
if err = newResponseError(resp, http.StatusOK); err != nil {
50+
return nil, err
5851
}
5952

6053
finalMember := &organization.Member{}
@@ -68,16 +61,13 @@ func (c *Client) GetMember(ctx context.Context, id string) (*organization.Member
6861
// DeleteMember deletes a detector.
6962
func (c *Client) DeleteMember(ctx context.Context, id string) error {
7063
resp, err := c.doRequest(ctx, "DELETE", OrganizationMemberAPIURL+"/"+id, nil, nil)
71-
if resp != nil {
72-
defer resp.Body.Close()
73-
}
7464
if err != nil {
7565
return err
7666
}
67+
defer resp.Body.Close()
7768

78-
if resp.StatusCode != http.StatusNoContent {
79-
message, _ := ioutil.ReadAll(resp.Body)
80-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
69+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
70+
return err
8171
}
8272
_, _ = io.Copy(ioutil.Discard, resp.Body)
8373

@@ -92,16 +82,13 @@ func (c *Client) InviteMember(ctx context.Context, inviteRequest *organization.C
9282
}
9383

9484
resp, err := c.doRequest(ctx, "POST", OrganizationMemberAPIURL, nil, bytes.NewReader(payload))
95-
if resp != nil {
96-
defer resp.Body.Close()
97-
}
9885
if err != nil {
9986
return nil, err
10087
}
88+
defer resp.Body.Close()
10189

102-
if resp.StatusCode != http.StatusOK {
103-
message, _ := ioutil.ReadAll(resp.Body)
104-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
90+
if err = newResponseError(resp, http.StatusOK); err != nil {
91+
return nil, err
10592
}
10693

10794
finalMember := &organization.Member{}
@@ -120,16 +107,13 @@ func (c *Client) UpdateMember(ctx context.Context, id string, updateRequest *org
120107
}
121108

122109
resp, err := c.doRequest(ctx, "PUT", OrganizationMemberAPIURL+"/"+id, nil, bytes.NewReader(payload))
123-
if resp != nil {
124-
defer resp.Body.Close()
125-
}
126110
if err != nil {
127111
return nil, err
128112
}
113+
defer resp.Body.Close()
129114

130-
if resp.StatusCode != http.StatusOK {
131-
message, _ := ioutil.ReadAll(resp.Body)
132-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
115+
if err = newResponseError(resp, http.StatusOK); err != nil {
116+
return nil, err
133117
}
134118

135119
finalMember := &organization.Member{}
@@ -148,16 +132,13 @@ func (c *Client) InviteMembers(ctx context.Context, inviteRequest *organization.
148132
}
149133

150134
resp, err := c.doRequest(ctx, "POST", OrganizationMembersAPIURL, nil, bytes.NewReader(payload))
151-
if resp != nil {
152-
defer resp.Body.Close()
153-
}
154135
if err != nil {
155136
return nil, err
156137
}
138+
defer resp.Body.Close()
157139

158-
if resp.StatusCode != http.StatusOK {
159-
message, _ := ioutil.ReadAll(resp.Body)
160-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
140+
if err = newResponseError(resp, http.StatusOK); err != nil {
141+
return nil, err
161142
}
162143

163144
finalMembers := &organization.InviteMembersRequest{}
@@ -177,16 +158,13 @@ func (c *Client) GetOrganizationMembers(ctx context.Context, limit int, query st
177158
params.Add("orderBy", orderBy)
178159

179160
resp, err := c.doRequest(ctx, "GET", OrganizationMemberAPIURL, params, nil)
180-
if resp != nil {
181-
defer resp.Body.Close()
182-
}
183161
if err != nil {
184162
return nil, err
185163
}
164+
defer resp.Body.Close()
186165

187-
if resp.StatusCode != http.StatusOK {
188-
message, _ := ioutil.ReadAll(resp.Body)
189-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
166+
if err = newResponseError(resp, http.StatusOK); err != nil {
167+
return nil, err
190168
}
191169

192170
finalMembers := &organization.MemberSearchResults{}

‎orgtoken.go

+15-31
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -25,16 +24,13 @@ func (c *Client) CreateOrgToken(ctx context.Context, tokenRequest *orgtoken.Crea
2524
}
2625

2726
resp, err := c.doRequest(ctx, "POST", TokenAPIURL, nil, bytes.NewReader(payload))
28-
if resp != nil {
29-
defer resp.Body.Close()
30-
}
3127
if err != nil {
3228
return nil, err
3329
}
30+
defer resp.Body.Close()
3431

35-
if resp.StatusCode != http.StatusOK {
36-
message, _ := ioutil.ReadAll(resp.Body)
37-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
32+
if err = newResponseError(resp, http.StatusOK); err != nil {
33+
return nil, err
3834
}
3935

4036
finalToken := &orgtoken.Token{}
@@ -49,16 +45,13 @@ func (c *Client) CreateOrgToken(ctx context.Context, tokenRequest *orgtoken.Crea
4945
func (c *Client) DeleteOrgToken(ctx context.Context, name string) error {
5046
encodedName := url.PathEscape(name)
5147
resp, err := c.doRequest(ctx, "DELETE", TokenAPIURL+"/"+encodedName, nil, nil)
52-
if resp != nil {
53-
defer resp.Body.Close()
54-
}
5548
if err != nil {
5649
return err
5750
}
51+
defer resp.Body.Close()
5852

59-
if resp.StatusCode != http.StatusNoContent {
60-
message, _ := ioutil.ReadAll(resp.Body)
61-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
53+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
54+
return err
6255
}
6356
_, _ = io.Copy(ioutil.Discard, resp.Body)
6457

@@ -69,16 +62,13 @@ func (c *Client) DeleteOrgToken(ctx context.Context, name string) error {
6962
func (c *Client) GetOrgToken(ctx context.Context, id string) (*orgtoken.Token, error) {
7063
encodedName := url.PathEscape(id)
7164
resp, err := c.doRequest(ctx, "GET", TokenAPIURL+"/"+encodedName, nil, nil)
72-
if resp != nil {
73-
defer resp.Body.Close()
74-
}
7565
if err != nil {
7666
return nil, err
7767
}
68+
defer resp.Body.Close()
7869

79-
if resp.StatusCode != http.StatusOK {
80-
message, _ := ioutil.ReadAll(resp.Body)
81-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
70+
if err = newResponseError(resp, http.StatusOK); err != nil {
71+
return nil, err
8272
}
8373

8474
finalToken := &orgtoken.Token{}
@@ -98,16 +88,13 @@ func (c *Client) UpdateOrgToken(ctx context.Context, id string, tokenRequest *or
9888

9989
encodedName := url.PathEscape(id)
10090
resp, err := c.doRequest(ctx, "PUT", TokenAPIURL+"/"+encodedName, nil, bytes.NewReader(payload))
101-
if resp != nil {
102-
defer resp.Body.Close()
103-
}
10491
if err != nil {
10592
return nil, err
10693
}
94+
defer resp.Body.Close()
10795

108-
if resp.StatusCode != http.StatusOK {
109-
message, _ := ioutil.ReadAll(resp.Body)
110-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
96+
if err = newResponseError(resp, http.StatusOK); err != nil {
97+
return nil, err
11198
}
11299

113100
finalToken := &orgtoken.Token{}
@@ -126,16 +113,13 @@ func (c *Client) SearchOrgTokens(ctx context.Context, limit int, name string, of
126113
params.Add("offset", strconv.Itoa(offset))
127114

128115
resp, err := c.doRequest(ctx, "GET", TokenAPIURL, params, nil)
129-
if resp != nil {
130-
defer resp.Body.Close()
131-
}
132116
if err != nil {
133117
return nil, err
134118
}
119+
defer resp.Body.Close()
135120

136-
if resp.StatusCode != http.StatusOK {
137-
message, _ := ioutil.ReadAll(resp.Body)
138-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
121+
if err = newResponseError(resp, http.StatusOK); err != nil {
122+
return nil, err
139123
}
140124

141125
finalTokens := &orgtoken.SearchResults{}

‎pagerduty_integration.go

+15-31
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -21,16 +20,13 @@ func (c *Client) CreatePagerDutyIntegration(ctx context.Context, pdi *integratio
2120
}
2221

2322
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
24-
if resp != nil {
25-
defer resp.Body.Close()
26-
}
2723
if err != nil {
2824
return nil, err
2925
}
26+
defer resp.Body.Close()
3027

31-
if resp.StatusCode != http.StatusOK {
32-
message, _ := ioutil.ReadAll(resp.Body)
33-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
28+
if err = newResponseError(resp, http.StatusOK); err != nil {
29+
return nil, err
3430
}
3531

3632
finalIntegration := integration.PagerDutyIntegration{}
@@ -44,16 +40,13 @@ func (c *Client) CreatePagerDutyIntegration(ctx context.Context, pdi *integratio
4440
// GetPagerDutyIntegration retrieves a PagerDuty integration.
4541
func (c *Client) GetPagerDutyIntegration(ctx context.Context, id string) (*integration.PagerDutyIntegration, error) {
4642
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
47-
if resp != nil {
48-
defer resp.Body.Close()
49-
}
5043
if err != nil {
5144
return nil, err
5245
}
46+
defer resp.Body.Close()
5347

54-
if resp.StatusCode != http.StatusOK {
55-
message, _ := ioutil.ReadAll(resp.Body)
56-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
48+
if err = newResponseError(resp, http.StatusOK); err != nil {
49+
return nil, err
5750
}
5851

5952
finalIntegration := integration.PagerDutyIntegration{}
@@ -71,16 +64,13 @@ func (c *Client) GetPagerDutyIntegrationByName(ctx context.Context, name string)
7164
params.Add("name", name)
7265

7366
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL, params, nil)
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
7767
if err != nil {
7868
return nil, err
7969
}
70+
defer resp.Body.Close()
8071

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
72+
if err = newResponseError(resp, http.StatusOK); err != nil {
73+
return nil, err
8474
}
8575

8676
integrationList := integration.PagerDutyIntegrationList{}
@@ -109,16 +99,13 @@ func (c *Client) UpdatePagerDutyIntegration(ctx context.Context, id string, pdi
10999
}
110100

111101
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
112-
if resp != nil {
113-
defer resp.Body.Close()
114-
}
115102
if err != nil {
116103
return nil, err
117104
}
105+
defer resp.Body.Close()
118106

119-
if resp.StatusCode != http.StatusOK {
120-
message, _ := ioutil.ReadAll(resp.Body)
121-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
107+
if err = newResponseError(resp, http.StatusOK); err != nil {
108+
return nil, err
122109
}
123110

124111
finalIntegration := integration.PagerDutyIntegration{}
@@ -132,16 +119,13 @@ func (c *Client) UpdatePagerDutyIntegration(ctx context.Context, id string, pdi
132119
// DeletePagerDutyIntegration deletes a PagerDuty integration.
133120
func (c *Client) DeletePagerDutyIntegration(ctx context.Context, id string) error {
134121
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
135-
if resp != nil {
136-
defer resp.Body.Close()
137-
}
138122
if err != nil {
139123
return err
140124
}
125+
defer resp.Body.Close()
141126

142-
if resp.StatusCode != http.StatusNoContent {
143-
message, _ := ioutil.ReadAll(resp.Body)
144-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
127+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
128+
return err
145129
}
146130
_, _ = io.Copy(ioutil.Discard, resp.Body)
147131

‎sessiontoken.go

+6-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -25,16 +24,13 @@ func (c *Client) CreateSessionToken(ctx context.Context, tokenRequest *sessionto
2524
// we need to explicitly pass an empty token (which means it wont get set in the header)
2625
// the API accepts either no token or a valid token, but not an empty token.
2726
resp, err := c.doRequestWithToken(ctx, "POST", SessionTokenAPIURL, nil, bytes.NewReader(payload), "")
28-
if resp != nil {
29-
defer resp.Body.Close()
30-
}
3127
if err != nil {
3228
return nil, err
3329
}
30+
defer resp.Body.Close()
3431

35-
if resp.StatusCode != http.StatusOK {
36-
message, _ := ioutil.ReadAll(resp.Body)
37-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
32+
if err = newResponseError(resp, http.StatusOK); err != nil {
33+
return nil, err
3834
}
3935

4036
sessionToken := &sessiontoken.Token{}
@@ -48,16 +44,13 @@ func (c *Client) CreateSessionToken(ctx context.Context, tokenRequest *sessionto
4844
// DeleteOrgToken deletes a token.
4945
func (c *Client) DeleteSessionToken(ctx context.Context, token string) error {
5046
resp, err := c.doRequestWithToken(ctx, "DELETE", SessionTokenAPIURL, nil, nil, token)
51-
if resp != nil {
52-
defer resp.Body.Close()
53-
}
5447
if err != nil {
5548
return err
5649
}
50+
defer resp.Body.Close()
5751

58-
if resp.StatusCode != http.StatusNoContent {
59-
message, _ := ioutil.ReadAll(resp.Body)
60-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
52+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
53+
return err
6154
}
6255
_, _ = io.Copy(ioutil.Discard, resp.Body)
6356

‎slack_integration.go

+12-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -20,16 +19,13 @@ func (c *Client) CreateSlackIntegration(ctx context.Context, si *integration.Sla
2019
}
2120

2221
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
23-
if resp != nil {
24-
defer resp.Body.Close()
25-
}
2622
if err != nil {
2723
return nil, err
2824
}
25+
defer resp.Body.Close()
2926

30-
if resp.StatusCode != http.StatusOK {
31-
message, _ := ioutil.ReadAll(resp.Body)
32-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
27+
if err = newResponseError(resp, http.StatusOK); err != nil {
28+
return nil, err
3329
}
3430

3531
finalIntegration := integration.SlackIntegration{}
@@ -43,16 +39,13 @@ func (c *Client) CreateSlackIntegration(ctx context.Context, si *integration.Sla
4339
// GetSlackIntegration retrieves a Slack integration.
4440
func (c *Client) GetSlackIntegration(ctx context.Context, id string) (*integration.SlackIntegration, error) {
4541
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
46-
if resp != nil {
47-
defer resp.Body.Close()
48-
}
4942
if err != nil {
5043
return nil, err
5144
}
45+
defer resp.Body.Close()
5246

53-
if resp.StatusCode != http.StatusOK {
54-
message, _ := ioutil.ReadAll(resp.Body)
55-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
47+
if err = newResponseError(resp, http.StatusOK); err != nil {
48+
return nil, err
5649
}
5750

5851
finalIntegration := integration.SlackIntegration{}
@@ -71,16 +64,13 @@ func (c *Client) UpdateSlackIntegration(ctx context.Context, id string, si *inte
7164
}
7265

7366
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
7767
if err != nil {
7868
return nil, err
7969
}
70+
defer resp.Body.Close()
8071

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
72+
if err = newResponseError(resp, http.StatusOK); err != nil {
73+
return nil, err
8474
}
8575

8676
finalIntegration := integration.SlackIntegration{}
@@ -94,16 +84,13 @@ func (c *Client) UpdateSlackIntegration(ctx context.Context, id string, si *inte
9484
// DeleteSlackIntegration deletes a Slack integration.
9585
func (c *Client) DeleteSlackIntegration(ctx context.Context, id string) error {
9686
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10087
if err != nil {
10188
return err
10289
}
90+
defer resp.Body.Close()
10391

104-
if resp.StatusCode != http.StatusNoContent {
105-
message, _ := ioutil.ReadAll(resp.Body)
106-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
92+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
93+
return err
10794
}
10895
_, _ = io.Copy(ioutil.Discard, resp.Body)
10996

‎slo.go

+5-9
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
8-
"github.com/signalfx/signalfx-go/slo"
97
"io"
108
"net/http"
9+
10+
"github.com/signalfx/signalfx-go/slo"
1111
)
1212

1313
const SloAPIURL = "/v2/slo"
@@ -47,17 +47,13 @@ func (c *Client) executeSloRequest(ctx context.Context, url string, method strin
4747
}
4848

4949
resp, err := c.doRequest(ctx, method, url, nil, body)
50-
if resp != nil {
51-
defer resp.Body.Close()
52-
}
53-
5450
if err != nil {
5551
return nil, err
5652
}
53+
defer resp.Body.Close()
5754

58-
if resp.StatusCode != expectedValidStatus {
59-
message, _ := io.ReadAll(resp.Body)
60-
return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
55+
if err = newResponseError(resp, expectedValidStatus); err != nil {
56+
return nil, err
6157
}
6258

6359
if resp.Body != nil {

‎team.go

+29-55
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"errors"
87
"fmt"
98
"io"
109
"io/ioutil"
@@ -26,16 +25,13 @@ func (c *Client) CreateTeam(ctx context.Context, t *team.CreateUpdateTeamRequest
2625
}
2726

2827
resp, err := c.doRequest(ctx, "POST", TeamAPIURL, nil, bytes.NewReader(payload))
29-
if resp != nil {
30-
defer resp.Body.Close()
31-
}
3228
if err != nil {
3329
return nil, err
3430
}
31+
defer resp.Body.Close()
3532

36-
if resp.StatusCode != http.StatusOK {
37-
message, _ := ioutil.ReadAll(resp.Body)
38-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
33+
if err = newResponseError(resp, http.StatusOK); err != nil {
34+
return nil, err
3935
}
4036

4137
finalTeam := &team.Team{}
@@ -49,15 +45,13 @@ func (c *Client) CreateTeam(ctx context.Context, t *team.CreateUpdateTeamRequest
4945
// DeleteTeam deletes a team.
5046
func (c *Client) DeleteTeam(ctx context.Context, id string) error {
5147
resp, err := c.doRequest(ctx, "DELETE", TeamAPIURL+"/"+id, nil, nil)
52-
if resp != nil {
53-
defer resp.Body.Close()
54-
}
5548
if err != nil {
5649
return err
5750
}
51+
defer resp.Body.Close()
5852

59-
if resp.StatusCode != http.StatusNoContent {
60-
return errors.New("Unexpected status code: " + resp.Status)
53+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
54+
return err
6155
}
6256
_, _ = io.Copy(ioutil.Discard, resp.Body)
6357

@@ -67,15 +61,13 @@ func (c *Client) DeleteTeam(ctx context.Context, id string) error {
6761
// GetTeam gets a team.
6862
func (c *Client) GetTeam(ctx context.Context, id string) (*team.Team, error) {
6963
resp, err := c.doRequest(ctx, "GET", TeamAPIURL+"/"+id, nil, nil)
70-
if resp != nil {
71-
defer resp.Body.Close()
72-
}
7364
if err != nil {
7465
return nil, err
7566
}
76-
if resp.StatusCode != http.StatusOK {
77-
message, _ := ioutil.ReadAll(resp.Body)
78-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
67+
defer resp.Body.Close()
68+
69+
if err = newResponseError(resp, http.StatusOK); err != nil {
70+
return nil, err
7971
}
8072

8173
finalTeam := &team.Team{}
@@ -94,15 +86,13 @@ func (c *Client) UpdateTeam(ctx context.Context, id string, t *team.CreateUpdate
9486
}
9587

9688
resp, err := c.doRequest(ctx, "PUT", TeamAPIURL+"/"+id, nil, bytes.NewReader(payload))
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10089
if err != nil {
10190
return nil, err
10291
}
103-
if resp.StatusCode != http.StatusOK {
104-
message, _ := ioutil.ReadAll(resp.Body)
105-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
92+
defer resp.Body.Close()
93+
94+
if err = newResponseError(resp, http.StatusOK); err != nil {
95+
return nil, err
10696
}
10797

10898
finalTeam := &team.Team{}
@@ -122,16 +112,13 @@ func (c *Client) SearchTeam(ctx context.Context, limit int, name string, offset
122112
params.Add("tags", tags)
123113

124114
resp, err := c.doRequest(ctx, "GET", TeamAPIURL, params, nil)
125-
if resp != nil {
126-
defer resp.Body.Close()
127-
}
128115
if err != nil {
129116
return nil, err
130117
}
118+
defer resp.Body.Close()
131119

132-
if resp.StatusCode != http.StatusOK {
133-
message, _ := ioutil.ReadAll(resp.Body)
134-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
120+
if err = newResponseError(resp, http.StatusOK); err != nil {
121+
return nil, err
135122
}
136123

137124
finalTeams := &team.SearchResults{}
@@ -147,16 +134,13 @@ func (c *Client) LinkDetectorToTeam(ctx context.Context, id string, detectorID s
147134
targetURL := fmt.Sprintf("%s/%s/detector/%s", TeamAPIURL, id, detectorID)
148135
resp, err := c.doRequest(ctx, "POST", targetURL, nil, nil)
149136

150-
if resp != nil {
151-
defer resp.Body.Close()
152-
}
153137
if err != nil {
154138
return err
155139
}
140+
defer resp.Body.Close()
156141

157-
if resp.StatusCode != http.StatusNoContent {
158-
message, _ := ioutil.ReadAll(resp.Body)
159-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
142+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
143+
return err
160144
}
161145

162146
return nil
@@ -167,16 +151,13 @@ func (c *Client) UnlinkDetectorFromTeam(ctx context.Context, id string, detector
167151
targetURL := fmt.Sprintf("%s/%s/detector/%s", TeamAPIURL, id, detectorID)
168152
resp, err := c.doRequest(ctx, "DELETE", targetURL, nil, nil)
169153

170-
if resp != nil {
171-
defer resp.Body.Close()
172-
}
173154
if err != nil {
174155
return err
175156
}
157+
defer resp.Body.Close()
176158

177-
if resp.StatusCode != http.StatusNoContent {
178-
message, _ := ioutil.ReadAll(resp.Body)
179-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
159+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
160+
return err
180161
}
181162

182163
return nil
@@ -186,17 +167,13 @@ func (c *Client) UnlinkDetectorFromTeam(ctx context.Context, id string, detector
186167
func (c *Client) LinkDashboardGroupToTeam(ctx context.Context, id string, dashboardGroupID string) error {
187168
targetURL := fmt.Sprintf("%s/%s/dashboardgroup/%s", TeamAPIURL, id, dashboardGroupID)
188169
resp, err := c.doRequest(ctx, "POST", targetURL, nil, nil)
189-
190-
if resp != nil {
191-
defer resp.Body.Close()
192-
}
193170
if err != nil {
194171
return err
195172
}
173+
defer resp.Body.Close()
196174

197-
if resp.StatusCode != http.StatusNoContent {
198-
message, _ := ioutil.ReadAll(resp.Body)
199-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
175+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
176+
return err
200177
}
201178

202179
return nil
@@ -207,16 +184,13 @@ func (c *Client) UnlinkDashboardGroupFromTeam(ctx context.Context, id string, da
207184
targetURL := fmt.Sprintf("%s/%s/dashboardgroup/%s", TeamAPIURL, id, dashboardGroupID)
208185
resp, err := c.doRequest(ctx, "DELETE", targetURL, nil, nil)
209186

210-
if resp != nil {
211-
defer resp.Body.Close()
212-
}
213187
if err != nil {
214188
return err
215189
}
190+
defer resp.Body.Close()
216191

217-
if resp.StatusCode != http.StatusNoContent {
218-
message, _ := ioutil.ReadAll(resp.Body)
219-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
192+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
193+
return err
220194
}
221195

222196
return nil

‎victor_ops_integration.go

+12-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -20,16 +19,13 @@ func (c *Client) CreateVictorOpsIntegration(ctx context.Context, oi *integration
2019
}
2120

2221
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
23-
if resp != nil {
24-
defer resp.Body.Close()
25-
}
2622
if err != nil {
2723
return nil, err
2824
}
25+
defer resp.Body.Close()
2926

30-
if resp.StatusCode != http.StatusOK {
31-
message, _ := ioutil.ReadAll(resp.Body)
32-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
27+
if err = newResponseError(resp, http.StatusOK); err != nil {
28+
return nil, err
3329
}
3430

3531
finalIntegration := integration.VictorOpsIntegration{}
@@ -43,16 +39,13 @@ func (c *Client) CreateVictorOpsIntegration(ctx context.Context, oi *integration
4339
// GetVictorOpsIntegration retrieves an VictorOps integration.
4440
func (c *Client) GetVictorOpsIntegration(ctx context.Context, id string) (*integration.VictorOpsIntegration, error) {
4541
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
46-
if resp != nil {
47-
defer resp.Body.Close()
48-
}
4942
if err != nil {
5043
return nil, err
5144
}
45+
defer resp.Body.Close()
5246

53-
if resp.StatusCode != http.StatusOK {
54-
message, _ := ioutil.ReadAll(resp.Body)
55-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
47+
if err = newResponseError(resp, http.StatusOK); err != nil {
48+
return nil, err
5649
}
5750

5851
finalIntegration := integration.VictorOpsIntegration{}
@@ -71,16 +64,13 @@ func (c *Client) UpdateVictorOpsIntegration(ctx context.Context, id string, oi *
7164
}
7265

7366
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
7767
if err != nil {
7868
return nil, err
7969
}
70+
defer resp.Body.Close()
8071

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
72+
if err = newResponseError(resp, http.StatusOK); err != nil {
73+
return nil, err
8474
}
8575

8676
finalIntegration := integration.VictorOpsIntegration{}
@@ -94,16 +84,13 @@ func (c *Client) UpdateVictorOpsIntegration(ctx context.Context, id string, oi *
9484
// DeleteVictorOpsIntegration deletes an VictorOps integration.
9585
func (c *Client) DeleteVictorOpsIntegration(ctx context.Context, id string) error {
9686
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10087
if err != nil {
10188
return err
10289
}
90+
defer resp.Body.Close()
10391

104-
if resp.StatusCode != http.StatusNoContent {
105-
message, _ := ioutil.ReadAll(resp.Body)
106-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
92+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
93+
return err
10794
}
10895
_, _ = io.Copy(ioutil.Discard, resp.Body)
10996

‎webhook_integration.go

+12-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"fmt"
87
"io"
98
"io/ioutil"
109
"net/http"
@@ -20,16 +19,13 @@ func (c *Client) CreateWebhookIntegration(ctx context.Context, oi *integration.W
2019
}
2120

2221
resp, err := c.doRequest(ctx, "POST", IntegrationAPIURL, nil, bytes.NewReader(payload))
23-
if resp != nil {
24-
defer resp.Body.Close()
25-
}
2622
if err != nil {
2723
return nil, err
2824
}
25+
defer resp.Body.Close()
2926

30-
if resp.StatusCode != http.StatusOK {
31-
message, _ := ioutil.ReadAll(resp.Body)
32-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
27+
if err = newResponseError(resp, http.StatusOK); err != nil {
28+
return nil, err
3329
}
3430

3531
finalIntegration := integration.WebhookIntegration{}
@@ -43,16 +39,13 @@ func (c *Client) CreateWebhookIntegration(ctx context.Context, oi *integration.W
4339
// GetWebhookIntegration retrieves an Webhook integration.
4440
func (c *Client) GetWebhookIntegration(ctx context.Context, id string) (*integration.WebhookIntegration, error) {
4541
resp, err := c.doRequest(ctx, "GET", IntegrationAPIURL+"/"+id, nil, nil)
46-
if resp != nil {
47-
defer resp.Body.Close()
48-
}
4942
if err != nil {
5043
return nil, err
5144
}
45+
defer resp.Body.Close()
5246

53-
if resp.StatusCode != http.StatusOK {
54-
message, _ := ioutil.ReadAll(resp.Body)
55-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
47+
if err = newResponseError(resp, http.StatusOK); err != nil {
48+
return nil, err
5649
}
5750

5851
finalIntegration := integration.WebhookIntegration{}
@@ -71,16 +64,13 @@ func (c *Client) UpdateWebhookIntegration(ctx context.Context, id string, oi *in
7164
}
7265

7366
resp, err := c.doRequest(ctx, "PUT", IntegrationAPIURL+"/"+id, nil, bytes.NewReader(payload))
74-
if resp != nil {
75-
defer resp.Body.Close()
76-
}
7767
if err != nil {
7868
return nil, err
7969
}
70+
defer resp.Body.Close()
8071

81-
if resp.StatusCode != http.StatusOK {
82-
message, _ := ioutil.ReadAll(resp.Body)
83-
return nil, fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
72+
if err = newResponseError(resp, http.StatusOK); err != nil {
73+
return nil, err
8474
}
8575

8676
finalIntegration := integration.WebhookIntegration{}
@@ -94,16 +84,13 @@ func (c *Client) UpdateWebhookIntegration(ctx context.Context, id string, oi *in
9484
// DeleteWebhookIntegration deletes an Webhook integration.
9585
func (c *Client) DeleteWebhookIntegration(ctx context.Context, id string) error {
9686
resp, err := c.doRequest(ctx, "DELETE", IntegrationAPIURL+"/"+id, nil, nil)
97-
if resp != nil {
98-
defer resp.Body.Close()
99-
}
10087
if err != nil {
10188
return err
10289
}
90+
defer resp.Body.Close()
10391

104-
if resp.StatusCode != http.StatusNoContent {
105-
message, _ := ioutil.ReadAll(resp.Body)
106-
return fmt.Errorf("Unexpected status code: %d: %s", resp.StatusCode, message)
92+
if err = newResponseError(resp, http.StatusNoContent); err != nil {
93+
return err
10794
}
10895
_, _ = io.Copy(ioutil.Discard, resp.Body)
10996

0 commit comments

Comments
 (0)
Please sign in to comment.