Skip to content

Commit

Permalink
use bytes.Reader to read the response body twice
Browse files Browse the repository at this point in the history
- improve debugging output by always outputting the entire body even when there are errors
- move response body close to FetchData function
  • Loading branch information
tedpearson committed Oct 22, 2024
1 parent 9a9b909 commit 8c403f4
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 10 deletions.
14 changes: 12 additions & 2 deletions internal/app/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ type PollRequest struct {
// FetchData calls the api to get data for a particular time period.
// Note that the api may return a PENDING status or actual data.
// However, parsing of the response is handled in ParseReader.
func FetchData(start, end time.Time, config SmartHubConfig, jwt string) (io.ReadCloser, error) {
func FetchData(start, end time.Time, config SmartHubConfig, jwt string) (*bytes.Reader, error) {
client := http.Client{}
pollRequest := PollRequest{
TimeFrame: "HOURLY",
Expand Down Expand Up @@ -117,5 +117,15 @@ func FetchData(start, end time.Time, config SmartHubConfig, jwt string) (io.Read
if err != nil {
return nil, err
}
return resp.Body, nil
defer func() {
if err := resp.Body.Close(); err != nil {
fmt.Println("Error: failed to close response body")
}
}()
buf := new(bytes.Buffer)
_, err = io.Copy(buf, resp.Body)
if err != nil {
return nil, err
}
return bytes.NewReader(buf.Bytes()), nil
}
18 changes: 10 additions & 8 deletions internal/app/parser.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"bytes"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -68,16 +69,17 @@ func (t *RetryableError) Error() string {

// ParseReader parses the json response received in FetchData from the SmartHub poll api.
// It can return a normal error, a RetryableError, or parsed ElectricUsage.
func ParseReader(readCloser io.ReadCloser, timezone string) ([]ElectricUsage, error) {
defer func() {
if err := readCloser.Close(); err != nil {
fmt.Println("Error: failed to close response body")
}
}()
reader := readCloser.(io.Reader)
func ParseReader(reader *bytes.Reader, timezone string) ([]ElectricUsage, error) {
if debug {
_, _ = fmt.Fprintln(os.Stderr, "\nDEBUG: Response from poll endpoint:")
reader = io.TeeReader(readCloser, os.Stderr)
_, err := reader.WriteTo(os.Stderr)
if err != nil {
return nil, err
}
_, err = reader.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
}
resp := &Response{}
err := json.NewDecoder(reader).Decode(resp)
Expand Down

0 comments on commit 8c403f4

Please sign in to comment.