Skip to content

Commit 933d18a

Browse files
authored
Improve error handling and migrate to zerolog (#35)
1 parent e639bf0 commit 933d18a

2 files changed

Lines changed: 52 additions & 40 deletions

File tree

client.go

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
"log"
87
"math"
98
"strings"
109

1110
finnhub "github.com/Finnhub-Stock-API/finnhub-go/v2"
11+
"github.com/rs/zerolog"
1212
"github.com/seabird-chat/seabird-go"
1313
"github.com/seabird-chat/seabird-go/pb"
1414
)
@@ -42,10 +42,11 @@ type SeabirdClient struct {
4242
context.Context
4343
*seabird.Client
4444
finnhubClient *finnhub.DefaultApiService
45+
logger zerolog.Logger
4546
}
4647

4748
// NewSeabirdClient returns a new seabird client
48-
func NewSeabirdClient(seabirdCoreURL, seabirdCoreToken, finnhubToken string) (*SeabirdClient, error) {
49+
func NewSeabirdClient(seabirdCoreURL, seabirdCoreToken, finnhubToken string, logger zerolog.Logger) (*SeabirdClient, error) {
4950
seabirdClient, err := seabird.NewClient(seabirdCoreURL, seabirdCoreToken)
5051
if err != nil {
5152
return nil, err
@@ -58,27 +59,36 @@ func NewSeabirdClient(seabirdCoreURL, seabirdCoreToken, finnhubToken string) (*S
5859
Context: context.Background(),
5960
Client: seabirdClient,
6061
finnhubClient: finnhub.NewAPIClient(finnhubCfg).DefaultApi,
62+
logger: logger,
6163
}, nil
6264
}
6365

6466
func (c *SeabirdClient) close() error {
6567
return c.Client.Close()
6668
}
6769

70+
func (c *SeabirdClient) reply(source *pb.ChannelSource, format string, args ...interface{}) {
71+
if err := c.MentionReplyf(source, format, args...); err != nil {
72+
c.logger.Error().Err(err).Str("channel_id", source.GetChannelId()).Msg("failed to send reply")
73+
}
74+
}
75+
6876
func (c *SeabirdClient) stockCallback(event *pb.CommandEvent) {
69-
// TODO: Request debugging
70-
log.Printf("Processing event: %s %s %s", event.Source, event.Command, event.Arg)
7177
ticker := strings.ToUpper(strings.TrimSpace(event.Arg))
7278

79+
cmdLog := c.logger.With().
80+
Str("command", event.Command).
81+
Str("ticker", ticker).
82+
Str("channel_id", event.Source.GetChannelId()).
83+
Logger()
84+
7385
profile2, _, err := c.finnhubClient.CompanyProfile2(c.Context).Symbol(ticker).Execute()
7486
if err != nil {
75-
// TODO: What do we do with the error?
76-
log.Println(err)
87+
cmdLog.Error().Err(err).Msg("finnhub CompanyProfile2 failed")
88+
c.reply(event.Source, "Unable to look up %s.", ticker)
7789
return
7890
}
7991

80-
log.Printf("profile2 is: %+v\n", profile2)
81-
8292
// If Finnhub fails to find ticker, we get a 200 back with empty values, so
8393
// we set a default ticker/company and only use the profile response if it
8494
// has valid values.
@@ -97,30 +107,31 @@ func (c *SeabirdClient) stockCallback(event *pb.CommandEvent) {
97107
// only consistent way to determine if a stock actually exists.
98108
if err != nil || quoteResp.ContentLength != -1 {
99109
if err != nil {
100-
log.Println(err)
110+
cmdLog.Error().Err(err).Msg("finnhub Quote failed")
111+
c.reply(event.Source, "Unable to fetch quote for %s.", ticker)
101112
return
102113
}
103-
c.MentionReplyf(event.Source, "Unable to find %s.", ticker)
104-
} else {
105-
// TODO: Don't hardcoded USD here - currency requires premium https://finnhub.io/docs/api#company-profile
106-
if event.Command == "stonk" || event.Command == "stonks" {
107-
stonks := "is STONKS ↗️"
108-
sign := stonkReplacements["+"]
109-
if *quote.C <= *quote.O {
110-
stonks = "is NOT STONKS ↘️"
111-
sign = stonkReplacements["-"]
112-
}
113-
114-
current := stonkify(fmt.Sprintf("$%.2f", *quote.C))
115-
change := stonkify(fmt.Sprintf("%.2f", math.Abs(float64(*quote.C)-float64(*quote.O))))
114+
c.reply(event.Source, "Unable to find %s.", ticker)
115+
return
116+
}
116117

117-
c.MentionReplyf(event.Source, "%s %s. %s (%s%s)", company, stonks, current, sign, change)
118-
} else {
119-
percentChange := ((*quote.C - *quote.O) / *quote.O) * 100
120-
c.MentionReplyf(event.Source, "%s - Open: $%.2f, Current: $%.2f (%+.2f%%)", company, *quote.O, *quote.C, percentChange)
118+
// TODO: Don't hardcoded USD here - currency requires premium https://finnhub.io/docs/api#company-profile
119+
if event.Command == "stonk" || event.Command == "stonks" {
120+
stonks := "is STONKS ↗️"
121+
sign := stonkReplacements["+"]
122+
if *quote.C <= *quote.O {
123+
stonks = "is NOT STONKS ↘️"
124+
sign = stonkReplacements["-"]
121125
}
122-
}
123126

127+
current := stonkify(fmt.Sprintf("$%.2f", *quote.C))
128+
change := stonkify(fmt.Sprintf("%.2f", math.Abs(float64(*quote.C)-float64(*quote.O))))
129+
130+
c.reply(event.Source, "%s %s. %s (%s%s)", company, stonks, current, sign, change)
131+
} else {
132+
percentChange := ((*quote.C - *quote.O) / *quote.O) * 100
133+
c.reply(event.Source, "%s - Open: $%.2f, Current: $%.2f (%+.2f%%)", company, *quote.O, *quote.C, percentChange)
134+
}
124135
}
125136

126137
// Run runs
@@ -136,7 +147,8 @@ func (c *SeabirdClient) Run() error {
136147
return err
137148
}
138149

139-
defer events.Close()
150+
c.logger.Info().Msg("event stream open")
151+
140152
for event := range events.C {
141153
switch v := event.GetInner().(type) {
142154
case *pb.Event_Command:
@@ -146,5 +158,9 @@ func (c *SeabirdClient) Run() error {
146158
}
147159
}
148160
}
149-
return errors.New("event stream closed")
161+
162+
if closeErr := events.Close(); closeErr != nil {
163+
return fmt.Errorf("event stream closed: %w", closeErr)
164+
}
165+
return errors.New("event stream closed without error")
150166
}

cmd/seabird-stock-plugin/main.go

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

33
import (
4-
"log"
54
"os"
65

76
stock "github.com/jaredledvina/seabird-stock-plugin"
@@ -23,29 +22,26 @@ func main() {
2322
}
2423

2524
logger = logger.With().Timestamp().Logger()
26-
logger.Level(zerolog.InfoLevel)
2725

2826
coreURL := os.Getenv("SEABIRD_HOST")
2927
coreToken := os.Getenv("SEABIRD_TOKEN")
3028
finnhubToken := os.Getenv("FINNHUB_TOKEN")
3129

3230
if coreURL == "" || coreToken == "" {
33-
log.Fatal("Missing SEABIRD_HOST or SEABIRD_TOKEN")
31+
logger.Fatal().Msg("Missing SEABIRD_HOST or SEABIRD_TOKEN")
3432
}
3533

3634
if finnhubToken == "" {
37-
log.Fatal("Missing FINNHUB_TOKEN")
35+
logger.Fatal().Msg("Missing FINNHUB_TOKEN")
3836
}
3937

40-
c, err := stock.NewSeabirdClient(coreURL, coreToken, finnhubToken)
38+
c, err := stock.NewSeabirdClient(coreURL, coreToken, finnhubToken, logger)
4139
if err != nil {
42-
log.Fatalf("Failed to connect to seabird-core: %s", err)
40+
logger.Fatal().Err(err).Msg("failed to dial seabird-core")
4341
}
44-
log.Printf("Successfully connected to seabird-core at %s", coreURL)
42+
logger.Info().Str("host", coreURL).Msg("dialed seabird-core")
4543

46-
err = c.Run()
47-
if err != nil {
48-
log.Fatal(err)
44+
if err := c.Run(); err != nil {
45+
logger.Fatal().Err(err).Msg("event stream terminated")
4946
}
50-
5147
}

0 commit comments

Comments
 (0)