Skip to content

Commit bcca50e

Browse files
authored
feat: Improve error message handling and avoid memory leaks (#100)
1 parent e1a2da8 commit bcca50e

File tree

15 files changed

+208
-284
lines changed

15 files changed

+208
-284
lines changed

go.mod

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ require (
99
github.com/apparentlymart/go-cidr v1.1.0 // indirect
1010
github.com/aws/aws-sdk-go v1.37.10 // indirect
1111
github.com/fatih/color v1.10.0 // indirect
12-
github.com/golang/protobuf v1.4.3 // indirect
13-
github.com/google/go-cmp v0.5.4 // indirect
1412
github.com/hashicorp/errwrap v1.1.0 // indirect
1513
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
1614
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
@@ -20,8 +18,8 @@ require (
2018
github.com/hashicorp/go-uuid v1.0.2 // indirect
2119
github.com/hashicorp/hcl/v2 v2.8.2 // indirect
2220
github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.3
23-
github.com/hashicorp/terraform-plugin-test/v2 v2.1.2 // indirect
2421
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect
22+
github.com/jmespath/go-jmespath v0.4.0
2523
github.com/klauspost/compress v1.11.7 // indirect
2624
github.com/mitchellh/copystructure v1.1.1 // indirect
2725
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
@@ -35,6 +33,5 @@ require (
3533
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
3634
golang.org/x/oauth2 v0.0.0-20210210192628-66670185b0cd // indirect
3735
google.golang.org/api v0.40.0 // indirect
38-
google.golang.org/appengine v1.6.7 // indirect
3936
google.golang.org/genproto v0.0.0-20210212180131-e7f2df4ecc2d // indirect
4037
)

go.sum

Lines changed: 8 additions & 123 deletions
Large diffs are not rendered by default.

sysdig/internal/client/monitor/alerts.go

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package monitor
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"io/ioutil"
87
"net/http"
@@ -13,26 +12,31 @@ func (c *sysdigMonitorClient) CreateAlert(ctx context.Context, alert Alert) (cre
1312
if err != nil {
1413
return
1514
}
16-
body, err := ioutil.ReadAll(response.Body)
17-
if err != nil {
15+
defer response.Body.Close()
16+
17+
if response.StatusCode != http.StatusOK {
18+
err = errorFromResponse(response)
1819
return
1920
}
2021

21-
if response.StatusCode != 200 {
22-
err = errors.New(string(body))
22+
body, err := ioutil.ReadAll(response.Body)
23+
if err != nil {
2324
return
2425
}
25-
26-
defer response.Body.Close()
27-
2826
return AlertFromJSON(body), nil
2927
}
3028

3129
func (c *sysdigMonitorClient) DeleteAlert(ctx context.Context, alertID int) error {
3230
response, err := c.doSysdigMonitorRequest(ctx, http.MethodDelete, c.alertURL(alertID), nil)
33-
31+
if err != nil {
32+
return err
33+
}
3434
defer response.Body.Close()
3535

36+
if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK {
37+
return errorFromResponse(response)
38+
}
39+
3640
return err
3741
}
3842

@@ -41,19 +45,17 @@ func (c *sysdigMonitorClient) UpdateAlert(ctx context.Context, alert Alert) (upd
4145
if err != nil {
4246
return
4347
}
48+
defer response.Body.Close()
4449

45-
body, err := ioutil.ReadAll(response.Body)
46-
if err != nil {
50+
if response.StatusCode != 200 {
51+
err = errorFromResponse(response)
4752
return
4853
}
4954

50-
if response.StatusCode != 200 {
51-
err = errors.New(string(body))
55+
body, err := ioutil.ReadAll(response.Body)
56+
if err != nil {
5257
return
5358
}
54-
55-
defer response.Body.Close()
56-
5759
return AlertFromJSON(body), nil
5860
}
5961

@@ -62,17 +64,17 @@ func (c *sysdigMonitorClient) GetAlertById(ctx context.Context, alertID int) (al
6264
if err != nil {
6365
return
6466
}
65-
body, err := ioutil.ReadAll(response.Body)
66-
if err != nil {
67-
return
68-
}
67+
defer response.Body.Close()
6968

7069
if response.StatusCode != 200 {
71-
err = errors.New(string(body))
70+
err = errorFromResponse(response)
7271
return
7372
}
7473

75-
defer response.Body.Close()
74+
body, err := ioutil.ReadAll(response.Body)
75+
if err != nil {
76+
return
77+
}
7678

7779
return AlertFromJSON(body), nil
7880
}

sysdig/internal/client/monitor/dashboards.go

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,76 +10,69 @@ import (
1010
)
1111

1212
func (client *sysdigMonitorClient) GetDashboardByID(ctx context.Context, ID int) (*model.Dashboard, error) {
13-
res, err := client.doSysdigMonitorRequest(ctx, http.MethodGet, client.getDashboardUrl(ID), nil)
13+
response, err := client.doSysdigMonitorRequest(ctx, http.MethodGet, client.getDashboardUrl(ID), nil)
1414
if err != nil {
1515
return nil, err
1616
}
17-
defer res.Body.Close()
17+
defer response.Body.Close()
1818

19-
body, err := ioutil.ReadAll(res.Body)
20-
if err != nil {
21-
return nil, nil
19+
if response.StatusCode != http.StatusOK {
20+
return nil, errorFromResponse(response)
2221
}
2322

24-
if res.StatusCode != http.StatusOK {
25-
return nil, fmt.Errorf(string(body))
23+
body, err := ioutil.ReadAll(response.Body)
24+
if err != nil {
25+
return nil, nil
2626
}
27-
2827
return model.DashboardFromJSON(body), nil
2928
}
3029

3130
func (client *sysdigMonitorClient) CreateDashboard(ctx context.Context, dashboard *model.Dashboard) (*model.Dashboard, error) {
32-
res, err := client.doSysdigMonitorRequest(ctx, http.MethodPost, client.getDashboardsUrl(), dashboard.ToJSON())
31+
response, err := client.doSysdigMonitorRequest(ctx, http.MethodPost, client.getDashboardsUrl(), dashboard.ToJSON())
3332
if err != nil {
3433
return nil, err
3534
}
36-
defer res.Body.Close()
35+
defer response.Body.Close()
3736

38-
body, err := ioutil.ReadAll(res.Body)
39-
if err != nil {
40-
return nil, err
37+
if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated {
38+
return nil, errorFromResponse(response)
4139
}
4240

43-
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated {
44-
return nil, fmt.Errorf(string(body))
41+
body, err := ioutil.ReadAll(response.Body)
42+
if err != nil {
43+
return nil, err
4544
}
46-
4745
return model.DashboardFromJSON(body), nil
4846
}
4947

5048
func (client *sysdigMonitorClient) UpdateDashboard(ctx context.Context, dashboard *model.Dashboard) (*model.Dashboard, error) {
51-
res, err := client.doSysdigMonitorRequest(ctx, http.MethodPut, client.getDashboardUrl(dashboard.ID), dashboard.ToJSON())
49+
response, err := client.doSysdigMonitorRequest(ctx, http.MethodPut, client.getDashboardUrl(dashboard.ID), dashboard.ToJSON())
5250
if err != nil {
5351
return nil, err
5452
}
55-
defer res.Body.Close()
53+
defer response.Body.Close()
5654

57-
body, err := ioutil.ReadAll(res.Body)
58-
if err != nil {
59-
return nil, err
55+
if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated {
56+
return nil, errorFromResponse(response)
6057
}
6158

62-
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated {
63-
return nil, fmt.Errorf(string(body))
59+
body, err := ioutil.ReadAll(response.Body)
60+
if err != nil {
61+
return nil, err
6462
}
6563

6664
return model.DashboardFromJSON(body), nil
6765
}
6866

6967
func (client *sysdigMonitorClient) DeleteDashboard(ctx context.Context, ID int) error {
70-
res, err := client.doSysdigMonitorRequest(ctx, http.MethodDelete, client.getDashboardUrl(ID), nil)
68+
response, err := client.doSysdigMonitorRequest(ctx, http.MethodDelete, client.getDashboardUrl(ID), nil)
7169
if err != nil {
7270
return err
7371
}
74-
defer res.Body.Close()
75-
76-
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusNoContent {
77-
body, err := ioutil.ReadAll(res.Body)
78-
if err != nil {
79-
return err
80-
}
72+
defer response.Body.Close()
8173

82-
return fmt.Errorf(string(body))
74+
if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK {
75+
return errorFromResponse(response)
8376
}
8477

8578
return nil
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package monitor
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"net/http"
7+
"strings"
8+
9+
"github.com/jmespath/go-jmespath"
10+
"github.com/spf13/cast"
11+
)
12+
13+
func errorFromResponse(response *http.Response) error {
14+
var data interface{}
15+
err := json.NewDecoder(response.Body).Decode(&data)
16+
if err != nil {
17+
return errors.New(response.Status)
18+
}
19+
20+
search, err := jmespath.Search("[message, errors[].[reason, message]][][] | join(', ', @)", data)
21+
if err != nil {
22+
return errors.New(response.Status)
23+
}
24+
25+
if searchArray, ok := search.([]interface{}); ok {
26+
return errors.New(strings.Join(cast.ToStringSlice(searchArray), ", "))
27+
}
28+
29+
return errors.New(cast.ToString(search))
30+
}

sysdig/internal/client/monitor/notification_channels.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package monitor
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"io/ioutil"
87
"net/http"
@@ -15,13 +14,12 @@ func (client *sysdigMonitorClient) GetNotificationChannelById(ctx context.Contex
1514
}
1615
defer response.Body.Close()
1716

18-
body, _ := ioutil.ReadAll(response.Body)
19-
2017
if response.StatusCode != http.StatusOK {
21-
err = errors.New(response.Status)
18+
err = errorFromResponse(response)
2219
return
2320
}
2421

22+
body, _ := ioutil.ReadAll(response.Body)
2523
nc = NotificationChannelFromJSON(body)
2624

2725
if nc.Version == 0 {
@@ -41,7 +39,7 @@ func (client *sysdigMonitorClient) GetNotificationChannelByName(ctx context.Cont
4139
body, _ := ioutil.ReadAll(response.Body)
4240

4341
if response.StatusCode != http.StatusOK {
44-
err = errors.New(response.Status)
42+
err = errorFromResponse(response)
4543
return
4644
}
4745

@@ -65,13 +63,12 @@ func (client *sysdigMonitorClient) CreateNotificationChannel(ctx context.Context
6563
}
6664
defer response.Body.Close()
6765

68-
body, _ := ioutil.ReadAll(response.Body)
69-
7066
if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated {
71-
err = errors.New(response.Status)
67+
err = errorFromResponse(response)
7268
return
7369
}
7470

71+
body, _ := ioutil.ReadAll(response.Body)
7572
nc = NotificationChannelFromJSON(body)
7673
return
7774
}
@@ -83,13 +80,12 @@ func (client *sysdigMonitorClient) UpdateNotificationChannel(ctx context.Context
8380
}
8481
defer response.Body.Close()
8582

86-
body, _ := ioutil.ReadAll(response.Body)
87-
8883
if response.StatusCode != http.StatusOK {
89-
err = errors.New(response.Status)
84+
err = errorFromResponse(response)
9085
return
9186
}
9287

88+
body, _ := ioutil.ReadAll(response.Body)
9389
nc = NotificationChannelFromJSON(body)
9490
return
9591
}
@@ -102,7 +98,7 @@ func (client *sysdigMonitorClient) DeleteNotificationChannel(ctx context.Context
10298
defer response.Body.Close()
10399

104100
if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK {
105-
return errors.New(response.Status)
101+
return errorFromResponse(response)
106102
}
107103
return nil
108104
}

sysdig/internal/client/monitor/teams.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (client *sysdigMonitorClient) DeleteTeam(ctx context.Context, id int) error
121121
defer response.Body.Close()
122122

123123
if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK {
124-
return errors.New(response.Status)
124+
return errorFromResponse(response)
125125
}
126126
return nil
127127
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package secure
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"net/http"
7+
"strings"
8+
9+
"github.com/jmespath/go-jmespath"
10+
"github.com/spf13/cast"
11+
)
12+
13+
func errorFromResponse(response *http.Response) error {
14+
var data interface{}
15+
err := json.NewDecoder(response.Body).Decode(&data)
16+
if err != nil {
17+
return errors.New(response.Status)
18+
}
19+
20+
search, err := jmespath.Search("[message, errors[].[reason, message]][][] | join(', ', @)", data)
21+
if err != nil {
22+
return errors.New(response.Status)
23+
}
24+
25+
if searchArray, ok := search.([]interface{}); ok {
26+
return errors.New(strings.Join(cast.ToStringSlice(searchArray), ", "))
27+
}
28+
29+
return errors.New(cast.ToString(search))
30+
}

0 commit comments

Comments
 (0)