Skip to content

Commit 8c403f4

Browse files
committed
use bytes.Reader to read the response body twice
- improve debugging output by always outputting the entire body even when there are errors - move response body close to FetchData function
1 parent 9a9b909 commit 8c403f4

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

internal/app/api.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ type PollRequest struct {
8181
// FetchData calls the api to get data for a particular time period.
8282
// Note that the api may return a PENDING status or actual data.
8383
// However, parsing of the response is handled in ParseReader.
84-
func FetchData(start, end time.Time, config SmartHubConfig, jwt string) (io.ReadCloser, error) {
84+
func FetchData(start, end time.Time, config SmartHubConfig, jwt string) (*bytes.Reader, error) {
8585
client := http.Client{}
8686
pollRequest := PollRequest{
8787
TimeFrame: "HOURLY",
@@ -117,5 +117,15 @@ func FetchData(start, end time.Time, config SmartHubConfig, jwt string) (io.Read
117117
if err != nil {
118118
return nil, err
119119
}
120-
return resp.Body, nil
120+
defer func() {
121+
if err := resp.Body.Close(); err != nil {
122+
fmt.Println("Error: failed to close response body")
123+
}
124+
}()
125+
buf := new(bytes.Buffer)
126+
_, err = io.Copy(buf, resp.Body)
127+
if err != nil {
128+
return nil, err
129+
}
130+
return bytes.NewReader(buf.Bytes()), nil
121131
}

internal/app/parser.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package app
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"errors"
67
"fmt"
@@ -68,16 +69,17 @@ func (t *RetryableError) Error() string {
6869

6970
// ParseReader parses the json response received in FetchData from the SmartHub poll api.
7071
// It can return a normal error, a RetryableError, or parsed ElectricUsage.
71-
func ParseReader(readCloser io.ReadCloser, timezone string) ([]ElectricUsage, error) {
72-
defer func() {
73-
if err := readCloser.Close(); err != nil {
74-
fmt.Println("Error: failed to close response body")
75-
}
76-
}()
77-
reader := readCloser.(io.Reader)
72+
func ParseReader(reader *bytes.Reader, timezone string) ([]ElectricUsage, error) {
7873
if debug {
7974
_, _ = fmt.Fprintln(os.Stderr, "\nDEBUG: Response from poll endpoint:")
80-
reader = io.TeeReader(readCloser, os.Stderr)
75+
_, err := reader.WriteTo(os.Stderr)
76+
if err != nil {
77+
return nil, err
78+
}
79+
_, err = reader.Seek(0, io.SeekStart)
80+
if err != nil {
81+
return nil, err
82+
}
8183
}
8284
resp := &Response{}
8385
err := json.NewDecoder(reader).Decode(resp)

0 commit comments

Comments
 (0)