Improve main error handling
This commit is contained in:
55
main.go
55
main.go
@@ -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)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-signals:
|
||||||
logging.LogWarn("Received SIGINT or SIGTERM signal, exiting")
|
logging.LogWarn("Received SIGINT or SIGTERM signal, exiting")
|
||||||
return nil
|
return nil
|
||||||
|
case err := <-common.ErrorsChan:
|
||||||
|
if errors.IsFatal(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logging.LogError("%s", fmt.Sprintf("%v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user