Write errors to log file.
All checks were successful
Build & Test / Main (push) Successful in 1m1s

This commit is contained in:
Sam Fredrickson 2024-03-22 22:54:32 -07:00
parent 270534c0d5
commit 97f4793ec3
2 changed files with 72 additions and 19 deletions

View File

@ -2,7 +2,10 @@ package main
import ( import (
"fmt" "fmt"
"io"
"log/slog"
"os" "os"
"path/filepath"
"strings" "strings"
"code.humancabbage.net/sam/moonmath/coindesk" "code.humancabbage.net/sam/moonmath/coindesk"
@ -19,6 +22,10 @@ var CLI struct {
} }
func main() { func main() {
logFile := setupLogging()
defer func() {
_ = logFile.Close()
}()
ctx := kong.Parse(&CLI) ctx := kong.Parse(&CLI)
if ctx.Error != nil { if ctx.Error != nil {
fail(ctx.Error) fail(ctx.Error)
@ -42,6 +49,35 @@ func main() {
} }
} }
func setupLogging() io.Closer {
homePath, err := os.UserHomeDir()
if err != nil {
panic(err)
}
programConfigPath := filepath.Join(homePath, ".moonmath")
err = os.MkdirAll(programConfigPath, 0755)
if err != nil {
panic(err)
}
errLogPath := filepath.Join(programConfigPath, "errors.log")
errLogFile, err := os.OpenFile(
errLogPath,
os.O_CREATE|os.O_APPEND|os.O_WRONLY,
0600,
)
if err != nil {
panic(err)
}
slog.SetDefault(slog.New(
slog.NewTextHandler(errLogFile, &slog.HandlerOptions{
Level: slog.LevelError,
})))
return errLogFile
}
func fail(err error) { func fail(err error) {
fmt.Printf("program error: %v\n", err) fmt.Printf("program error: %v\n", err)
os.Exit(1) os.Exit(1)

View File

@ -3,6 +3,7 @@ package asset
import ( import (
"context" "context"
"fmt" "fmt"
"log/slog"
"time" "time"
"code.humancabbage.net/sam/moonmath/coindesk" "code.humancabbage.net/sam/moonmath/coindesk"
@ -109,31 +110,16 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
case refresh: case refresh:
m.refreshing = true m.refreshing = true
return m, tea.Batch( return m, tea.Batch(
func() tea.Msg { m.resumeIndicator,
return m.indicator.Tick() m.refresh,
},
func() tea.Msg {
// TODO: log errors
_ = m.math.Refresh(context.TODO())
return Msg{m.math.Asset, m.math}
},
) )
case moon.Math: case moon.Math:
m.math = msg m.math = msg
refillProperties(&m) refillProperties(&m)
refillProjections(&m) refillProjections(&m)
return m, tea.Batch( return m, tea.Batch(
// schedule the next refresh m.stopIndicator(),
tea.Tick(time.Second*30, m.scheduleRefresh(),
func(t time.Time) tea.Msg {
return Msg{m.math.Asset, refresh{}}
}),
// wait a bit to stop the indicator, so that it's more obvious
// even when the refresh completes quickly.
tea.Tick(time.Millisecond*500,
func(t time.Time) tea.Msg {
return Msg{m.math.Asset, stopIndicator{}}
}),
) )
case stopIndicator: case stopIndicator:
m.refreshing = false m.refreshing = false
@ -153,6 +139,37 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
type refresh struct{} type refresh struct{}
type stopIndicator struct{} type stopIndicator struct{}
func (m Model) refresh() tea.Msg {
err := m.math.Refresh(context.TODO())
if err != nil {
slog.Error("refresh",
"asset", m.math.Asset,
"err", err,
)
}
return Msg{m.math.Asset, m.math}
}
func (m Model) resumeIndicator() tea.Msg {
return m.indicator.Tick()
}
func (m Model) scheduleRefresh() tea.Cmd {
return tea.Tick(time.Second*30,
func(t time.Time) tea.Msg {
return Msg{m.math.Asset, refresh{}}
})
}
func (m Model) stopIndicator() tea.Cmd {
// wait a bit to stop the indicator, so that it's more obvious
// even when the refresh completes quickly.
return tea.Tick(time.Millisecond*500,
func(t time.Time) tea.Msg {
return Msg{m.math.Asset, stopIndicator{}}
})
}
func refillProperties(m *Model) { func refillProperties(m *Model) {
rows := []table.Row{ rows := []table.Row{
{"Asset", string(m.math.Asset)}, {"Asset", string(m.math.Asset)},