From 3fbb87d821ac8af1784274709d07e490d1471b57 Mon Sep 17 00:00:00 2001 From: Massaki Archambault Date: Sun, 3 Oct 2021 18:02:25 -0400 Subject: [PATCH] improve error handling --- exporter.go | 30 ++++++++++++++++++++++-------- heliumapi/accounts.go | 5 ++++- heliumapi/query.go | 22 ++++++++++++++++------ 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/exporter.go b/exporter.go index 9a6a6b9..8852aef 100644 --- a/exporter.go +++ b/exporter.go @@ -47,13 +47,6 @@ type Account struct { Tx AccountTx } -type AccountTx struct { - DepositTotal int - WithdrawalTotal int - LastUpdate time.Time - UpdateLock sync.Mutex -} - func NewAccount(address string) Account { return Account{ Address: address, @@ -65,6 +58,13 @@ func NewAccount(address string) Account { } } +type AccountTx struct { + DepositTotal int + WithdrawalTotal int + LastUpdate time.Time + UpdateLock sync.Mutex +} + const ( namespace = "helium" blockchain_oracle_factor = 100000000 @@ -449,13 +449,27 @@ func (e *Exporter) collectAccountRewardsTotalMetrics(wg *sync.WaitGroup, ch chan func (e *Exporter) collectAccountTransactionsMetrics(wg *sync.WaitGroup, ch chan<- prometheus.Metric, account *Account) { defer wg.Done() + activityTypes := []string{ + "add_gateway_v1", + "assert_location_v1", + "assert_location_v2", + "payment_v1", + "payment_v2", + "rewards_v1", + "rewards_v2", + "stake_validator_v1", + "token_burn_v1", + "transfer_hotspot_v1", + "unstake_validator_v1", + } + // we can only want to allow a single instance of the routine doing // calculations on the deposited and widthdrawn total account.Tx.UpdateLock.Lock() defer account.Tx.UpdateLock.Unlock() now := time.Now() - activities, err := heliumapi.GetActivityForAccount(account.Address, []string{}, &account.Tx.LastUpdate, &now) + activities, err := heliumapi.GetActivityForAccount(account.Address, activityTypes, &account.Tx.LastUpdate, &now) if err != nil { log.Println(err) return diff --git a/heliumapi/accounts.go b/heliumapi/accounts.go index ca11bc0..ed4eab9 100644 --- a/heliumapi/accounts.go +++ b/heliumapi/accounts.go @@ -3,6 +3,7 @@ package heliumapi import ( "encoding/json" "fmt" + "strings" "time" "github.com/helium-blockchain-exporter/heliumapi/activity" @@ -31,7 +32,9 @@ func GetAccountForAddress(account string) (*Account, error) { // query https://docs.helium.com/api/blockchain/accounts#activity-for-account func GetActivityForAccount(account string, filterTypes []string, minTime *time.Time, maxTime *time.Time) (*activity.Activities, error) { path := "/v1/accounts/" + account + "/activity" - params := map[string]string{} + params := map[string]string{ + "filter_types": strings.Join(filterTypes, ","), + } if minTime != nil { params["min_time"] = minTime.UTC().Format("2006-01-02T15:04:05Z") } diff --git a/heliumapi/query.go b/heliumapi/query.go index a544a82..26236fc 100644 --- a/heliumapi/query.go +++ b/heliumapi/query.go @@ -49,14 +49,19 @@ func getHeliumApi(path string, params *map[string]string) ([]byte, error) { // query the api resp, err := client.Do(req) if err != nil { - return nil, fmt.Errorf("failed to query %v: %v", path, err) + return nil, fmt.Errorf("failed to query %v: %v", req.URL.RequestURI(), err) } defer resp.Body.Close() + // validate the response status + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to query %v: http status %v", req.URL.RequestURI(), resp.StatusCode) + } + // read the response body body, err := ioutil.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("failed to read response body of %v: %v", path, err) + return nil, fmt.Errorf("failed to read response body of %v: %v", req.URL.RequestURI(), err) } return body, nil @@ -86,22 +91,27 @@ func getHeliumApiWithCursor(path string, params *map[string]string) ([][]byte, e // query the api resp, err := client.Do(req) if err != nil { - return nil, fmt.Errorf("failed to query %v: %v", path, err) + return nil, fmt.Errorf("failed to query %v: %v", req.URL.RequestURI(), err) } defer resp.Body.Close() // read the response body and add it to the result array body, err := ioutil.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("failed to read response body of %v: %v", path, err) + return nil, fmt.Errorf("failed to read response body of %v: %v", req.URL.RequestURI(), err) } res = append(res, body) + // validate the response status + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to query %v: http status %v", req.URL.RequestURI(), resp.StatusCode) + } + // parse the response body for a cursor respCursor.Cursor = "" err = json.Unmarshal(body, &respCursor) if err != nil { - return nil, fmt.Errorf("failed to unmarshal response from %v: %v", path, err) + return nil, fmt.Errorf("failed to unmarshal response from %v: %v", req.URL.RequestURI(), err) } // continue querying until there is no longer a cursor @@ -109,7 +119,7 @@ func getHeliumApiWithCursor(path string, params *map[string]string) ([][]byte, e params = &map[string]string{"cursor": respCursor.Cursor} req, err = createGetRequest(path, *params) if err != nil { - return nil, fmt.Errorf("failed to create query request %v: %v", path, err) + return nil, fmt.Errorf("failed to create query request %v: %v", req.URL.RequestURI(), err) } } else { break