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