Graceful panic/recover for market data errors

master
Michael Dvorkin 11 years ago
parent 391520c95a
commit 7accc918cb
  1. 10
      layout.go
  2. 36
      yahoo_market.go

@ -48,7 +48,11 @@ func (self *Layout) Initialize() *Layout {
}
//-----------------------------------------------------------------------------
func (self *Layout) Market(m *Market) string {
func (self *Layout) Market(market *Market) string {
if ok, err := market.Ok(); !ok {
return err
}
markup := `{{.Dow.name}}: {{.Dow.change}} ({{.Dow.percent}}) at {{.Dow.latest}}, {{.Sp500.name}}: {{.Sp500.change}} ({{.Sp500.percent}}) at {{.Sp500.latest}}, {{.Nasdaq.name}}: {{.Nasdaq.change}} ({{.Nasdaq.percent}}) at {{.Nasdaq.latest}}
{{.Advances.name}}: {{.Advances.nyse}} ({{.Advances.nysep}}) on NYSE and {{.Advances.nasdaq}} ({{.Advances.nasdaqp}}) on Nasdaq. {{.Declines.name}}: {{.Declines.nyse}} ({{.Declines.nysep}}) on NYSE and {{.Declines.nasdaq}} ({{.Declines.nasdaqp}}) on Nasdaq {{if .IsClosed}}<right>U.S. markets closed</right>{{end}}
New highs: {{.Highs.nyse}} on NYSE and {{.Highs.nasdaq}} on Nasdaq. New lows: {{.Lows.nyse}} on NYSE and {{.Lows.nasdaq}} on Nasdaq.`
@ -59,8 +63,8 @@ New highs: {{.Highs.nyse}} on NYSE and {{.Highs.nasdaq}} on Nasdaq. New lows: {{
}
buffer := new(bytes.Buffer)
highlight(m.Dow, m.Sp500, m.Nasdaq)
if err = template.Execute(buffer, m); err != nil {
highlight(market.Dow, market.Sp500, market.Nasdaq)
if err := template.Execute(buffer, market); err != nil {
panic(err)
}

@ -5,6 +5,7 @@
package mop
import (
`fmt`
`bytes`
`io/ioutil`
`net/http`
@ -12,8 +13,9 @@ import (
`strings`
)
const url = `http://finance.yahoo.com/marketupdate/overview`
type Market struct {
regex *regexp.Regexp
IsClosed bool
Dow map[string]string
Nasdaq map[string]string
@ -23,6 +25,8 @@ type Market struct {
Unchanged map[string]string
Highs map[string]string
Lows map[string]string
regex *regexp.Regexp
errors string
}
//-----------------------------------------------------------------------------
@ -36,6 +40,7 @@ func (self *Market) Initialize() *Market {
self.Unchanged = make(map[string]string)
self.Highs = make(map[string]string)
self.Lows = make(map[string]string)
self.errors = ``
const any = `\s*<.+?>`
const some = `<.+?`
@ -61,13 +66,19 @@ func (self *Market) Initialize() *Market {
}
//-----------------------------------------------------------------------------
func (self *Market) Fetch() *Market {
response, err := http.Get(`http://finance.yahoo.com/marketupdate/overview`)
func (self *Market) Fetch() (this *Market) {
this = self // <-- This ensures we return correct self in case of panic attack.
defer func() {
if err := recover(); err != nil {
self.errors = fmt.Sprintf("Error fetching market data...\n%s", err)
}
}()
response, err := http.Get(url)
if err != nil {
panic(err)
}
// Fetch response and get its body.
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
@ -83,6 +94,11 @@ func (self *Market) Format() string {
return new(Layout).Initialize().Market(self)
}
//-----------------------------------------------------------------------------
func (self *Market) Ok() (bool, string) {
return self.errors == ``, self.errors
}
// private
//-----------------------------------------------------------------------------
func (self *Market) check_if_market_open(body []byte) []byte {
@ -107,15 +123,9 @@ func (self *Market) trim(body []byte) []byte {
//-----------------------------------------------------------------------------
func (self *Market) extract(snippet []byte) *Market {
matches := self.regex.FindAllStringSubmatch(string(snippet), -1)
// if len(matches) > 0 {
// fmt.Printf("%d matches\n", len(matches[0]))
// for i, str := range matches[0][1:] {
// fmt.Printf("%d) [%s]\n", i, str)
// }
// } else {
// println(`No matches`)
// }
if len(matches) < 1 || len(matches[0]) < 37 {
panic(`Unable to parse ` + url)
}
self.Dow[`name`] = matches[0][1]
self.Dow[`latest`] = matches[0][2]

Loading…
Cancel
Save