From c7ca29a6d74d45d8825a7ac94f5716a537528bd8 Mon Sep 17 00:00:00 2001 From: Adrian Gallagher Date: Tue, 27 Aug 2019 10:47:47 +1000 Subject: [PATCH] Remove unnecessary log.Fatals and suboptimal os.Exits (#343) Engine fixes up the rest for exchange setup loading --- communications/telegram/telegram.go | 59 ++++++++++++++++---- currency/coinmarketcap/coinmarketcap.go | 16 ++---- currency/coinmarketcap/coinmarketcap_test.go | 9 ++- currency/storage.go | 11 +++- exchange.go | 3 - exchanges/mock/recording.go | 3 +- main.go | 3 + 7 files changed, 74 insertions(+), 30 deletions(-) diff --git a/communications/telegram/telegram.go b/communications/telegram/telegram.go index 8d6a5377..66ce70ab 100644 --- a/communications/telegram/telegram.go +++ b/communications/telegram/telegram.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "net/http" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/communications/base" @@ -43,9 +44,16 @@ const ( talkRoot = "GoCryptoTrader bot" ) +var ( + // ErrWaiter is the default timer to wait if an err occurs + // before retrying after successfully connecting + ErrWaiter = time.Second * 30 +) + // Telegram is the overarching type across this package type Telegram struct { base.Base + initConnected bool Token string Offset int64 AuthorisedClients []int64 @@ -64,6 +72,8 @@ func (t *Telegram) Connect() error { if err := t.TestConnection(); err != nil { return err } + + log.Debugln("Telegram: Connected successfully!") t.Connected = true go t.PollerStart() return nil @@ -71,9 +81,10 @@ func (t *Telegram) Connect() error { // PushEvent sends an event to a supplied recipient list via telegram func (t *Telegram) PushEvent(event base.Event) error { + msg := fmt.Sprintf("Type: %s Details: %s GainOrLoss: %s", + event.Type, event.TradeDetails, event.GainLoss) for i := range t.AuthorisedClients { - err := t.SendMessage(fmt.Sprintf("Type: %s Details: %s GainOrLoss: %s", - event.Type, event.TradeDetails, event.GainLoss), t.AuthorisedClients[i]) + err := t.SendMessage(msg, t.AuthorisedClients[i]) if err != nil { return err } @@ -83,12 +94,25 @@ func (t *Telegram) PushEvent(event base.Event) error { // PollerStart starts the long polling sequence func (t *Telegram) PollerStart() { - t.InitialConnect() + errWait := func(err error) { + log.Error(err) + time.Sleep(ErrWaiter) + } for { + if !t.initConnected { + err := t.InitialConnect() + if err != nil { + errWait(err) + continue + } + t.initConnected = true + } + resp, err := t.GetUpdates() if err != nil { - log.Error(err) + errWait(err) + continue } for i := range resp.Result { @@ -96,7 +120,8 @@ func (t *Telegram) PollerStart() { if string(resp.Result[i].Message.Text[0]) == "/" { err = t.HandleMessages(resp.Result[i].Message.Text, resp.Result[i].Message.From.ID) if err != nil { - log.Error(err) + log.Errorf("Telegram: Unable to HandleMessages. Error: %s\n", err) + continue } } t.Offset = resp.Result[i].UpdateID @@ -107,14 +132,14 @@ func (t *Telegram) PollerStart() { // InitialConnect sets offset, and sends a welcome greeting to any associated // IDs -func (t *Telegram) InitialConnect() { +func (t *Telegram) InitialConnect() error { resp, err := t.GetUpdates() if err != nil { - log.Fatal(err) + return err } if !resp.Ok { - log.Fatal(resp.Description) + return errors.New(resp.Description) } warmWelcomeList := make(map[string]int64) @@ -127,17 +152,25 @@ func (t *Telegram) InitialConnect() { for userName, ID := range warmWelcomeList { err = t.SendMessage(fmt.Sprintf("GoCryptoTrader bot has connected: Hello, %s!", userName), ID) if err != nil { - log.Fatal(err) + log.Errorf("Telegram: Unable to send welcome message. Error: %s\n", err) + continue } } + if len(resp.Result) == 0 { - return + return nil } + t.Offset = resp.Result[len(resp.Result)-1].UpdateID + return nil } // HandleMessages handles incoming message from the long polling routine func (t *Telegram) HandleMessages(text string, chatID int64) error { + if t.Verbose { + log.Debugf("Telegram: Received message: %s\n", text) + } + switch { case common.StringContains(text, cmdHelp): return t.SendMessage(fmt.Sprintf("%s: %s", talkRoot, cmdHelpReply), chatID) @@ -161,7 +194,7 @@ func (t *Telegram) HandleMessages(text string, chatID int64) error { return t.SendMessage(fmt.Sprintf("%s: %s", talkRoot, t.GetPortfolio()), chatID) default: - return t.SendMessage(fmt.Sprintf("command %s not recognized", text), chatID) + return t.SendMessage(fmt.Sprintf("Command %s not recognized", text), chatID) } } @@ -214,6 +247,10 @@ func (t *Telegram) SendMessage(text string, chatID int64) error { if !resp.Ok { return errors.New(resp.Description) } + + if t.Verbose { + log.Debugf("Telegram: Sent '%s'\n", text) + } return nil } diff --git a/currency/coinmarketcap/coinmarketcap.go b/currency/coinmarketcap/coinmarketcap.go index bebaa791..f34f97b3 100644 --- a/currency/coinmarketcap/coinmarketcap.go +++ b/currency/coinmarketcap/coinmarketcap.go @@ -8,7 +8,6 @@ package coinmarketcap import ( "errors" "fmt" - "log" "net/http" "net/url" "strconv" @@ -80,18 +79,15 @@ func (c *Coinmarketcap) SetDefaults() { } // Setup sets user configuration -func (c *Coinmarketcap) Setup(conf Settings) { +func (c *Coinmarketcap) Setup(conf Settings) error { if !conf.Enabled { c.Enabled = false - } else { - c.Enabled = true - c.Verbose = conf.Verbose - c.APIkey = conf.APIkey - err := c.SetAccountPlan(conf.AccountPlan) - if err != nil { - log.Fatal(err) - } } + + c.Enabled = true + c.Verbose = conf.Verbose + c.APIkey = conf.APIkey + return c.SetAccountPlan(conf.AccountPlan) } // GetCryptocurrencyInfo returns all static metadata for one or more diff --git a/currency/coinmarketcap/coinmarketcap_test.go b/currency/coinmarketcap/coinmarketcap_test.go index fed6268a..470d5ba7 100644 --- a/currency/coinmarketcap/coinmarketcap_test.go +++ b/currency/coinmarketcap/coinmarketcap_test.go @@ -41,7 +41,14 @@ func TestSetup(t *testing.T) { cfg.Enabled = true cfg.AccountPlan = "basic" - c.Setup(cfg) + if err := c.Setup(cfg); err != nil { + t.Error(err) + } + + cfg.AccountPlan = "meow" + if err := c.Setup(cfg); err == nil { + t.Error("expected err when invalid account plan is specified") + } } func TestCheckAccountPlan(t *testing.T) { diff --git a/currency/storage.go b/currency/storage.go index 752c52af..cebc28dc 100644 --- a/currency/storage.go +++ b/currency/storage.go @@ -116,15 +116,20 @@ func (s *Storage) RunUpdater(overrides BotOverrides, settings *MainConfiguration log.Debugf("Setting up currency analysis system with Coinmarketcap...") c := &coinmarketcap.Coinmarketcap{} c.SetDefaults() - c.Setup(coinmarketcap.Settings{ + err := c.Setup(coinmarketcap.Settings{ Name: settings.CryptocurrencyProvider.Name, Enabled: true, AccountPlan: settings.CryptocurrencyProvider.AccountPlan, APIkey: settings.CryptocurrencyProvider.APIkey, Verbose: settings.CryptocurrencyProvider.Verbose, }) - - s.currencyAnalysis = c + if err != nil { + log.Errorf("Unable to setup CoinMarketCap analysis. Error: %s", err) + c = nil + settings.CryptocurrencyProvider.Enabled = false + } else { + s.currencyAnalysis = c + } } if filePath == "" { diff --git a/exchange.go b/exchange.go index 4e6a0c39..b8f8c731 100644 --- a/exchange.go +++ b/exchange.go @@ -258,7 +258,4 @@ func SetupExchanges() { ) } wg.Wait() - if len(bot.exchanges) == 0 { - log.Fatalf("No exchanges were able to be loaded. Exiting") - } } diff --git a/exchanges/mock/recording.go b/exchanges/mock/recording.go index 281eabad..c15f4d58 100644 --- a/exchanges/mock/recording.go +++ b/exchanges/mock/recording.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io/ioutil" - "log" "net/http" "net/url" "os" @@ -163,7 +162,7 @@ func HTTPRecord(res *http.Response, service string, respContents []byte) error { mockRespVals, urlErr := url.ParseQuery(mockResponses[i].BodyParams) if urlErr != nil { - log.Fatal(urlErr) + return urlErr } if MatchURLVals(respQueryVals, mockRespVals) { diff --git a/main.go b/main.go index c8080aab..d8f43fc3 100644 --- a/main.go +++ b/main.go @@ -124,6 +124,9 @@ func main() { log.Debugf("Global HTTP request timeout: %v.\n", common.HTTPClient.Timeout) SetupExchanges() + if len(bot.exchanges) == 0 { + log.Fatal("No exchanges were able to be loaded. Exiting") + } log.Debugf("Starting communication mediums..") cfg := bot.config.GetCommunicationsConfig()