Improve main error handling

This commit is contained in:
2025-02-26 10:37:09 +02:00
parent e8e26ec76a
commit 8399225046

59
main.go
View File

@@ -1,14 +1,16 @@
package main package main
import ( import (
"fmt"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"gemini-grc/common" "gemini-grc/common"
"gemini-grc/common/blackList"
"gemini-grc/config" "gemini-grc/config"
"gemini-grc/db" "gemini-grc/db"
"gemini-grc/gemini" "gemini-grc/errors"
"gemini-grc/logging" "gemini-grc/logging"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@@ -20,42 +22,61 @@ func main() {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
zerolog.SetGlobalLevel(config.CONFIG.LogLevel) zerolog.SetGlobalLevel(config.CONFIG.LogLevel)
zlog.Logger = zlog.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "[2006-01-02 15:04:05]"}) zlog.Logger = zlog.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "[2006-01-02 15:04:05]"})
if err := runApp(); err != nil { err := runApp()
logging.LogError("Application error: %w", err) if err != nil {
var asErr *errors.Error
if errors.As(err, &asErr) {
logging.LogError("Unexpected error: %v", err)
_, _ = fmt.Fprintf(os.Stderr, "Unexpected error: %v", err)
} else {
logging.LogError("Unexpected error: %v", err)
}
os.Exit(1) os.Exit(1)
} }
} }
func runApp() error { func runApp() (err error) {
logging.LogInfo("Starting up. Press Ctrl+C to exit") logging.LogInfo("gemcrawl %s starting up. Press Ctrl+C to exit", common.VERSION)
signals := make(chan os.Signal, 1) signals := make(chan os.Signal, 1)
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
_db := db.ConnectToDB() _db, err := db.ConnectToDB()
if err != nil {
return err
}
defer func(db *sqlx.DB) { defer func(db *sqlx.DB) {
err := db.Close() _ = db.Close()
if err != nil {
// TODO properly log & hangle error
panic(err)
}
}(_db) }(_db)
gemini.LoadBlacklist() err = blackList.LoadBlacklist()
if err != nil {
return err
}
common.StatusChan = make(chan common.WorkerStatus, config.CONFIG.NumOfWorkers) common.StatusChan = make(chan common.WorkerStatus, config.CONFIG.NumOfWorkers)
common.ErrorsChan = make(chan error, config.CONFIG.NumOfWorkers)
// If there's an argument, visit this // If there's an argument, visit this
// URL only and don't spawn other workers // URL only and don't spawn other workers
if len(os.Args) > 1 { if len(os.Args) > 1 {
url := os.Args[1] url := os.Args[1]
gemini.CrawlOneURL(_db, &url) err = common.CrawlOneURL(_db, &url)
return nil return err
} else {
go gemini.SpawnWorkers(config.CONFIG.NumOfWorkers, _db)
} }
<-signals go common.SpawnWorkers(config.CONFIG.NumOfWorkers, _db)
logging.LogWarn("Received SIGINT or SIGTERM signal, exiting")
return nil for {
select {
case <-signals:
logging.LogWarn("Received SIGINT or SIGTERM signal, exiting")
return nil
case err := <-common.ErrorsChan:
if errors.IsFatal(err) {
return err
}
logging.LogError("%s", fmt.Sprintf("%v", err))
}
}
} }