Commit 94040035 authored by Jacob Vosmaer's avatar Jacob Vosmaer Committed by Nick Thomas

Restructure error handling in main()

parent 8b157fd2
---
title: Restructure error handling in main()
merge_request: 633
author:
type: fixed
...@@ -59,7 +59,7 @@ func startLogging(config logConfiguration) (io.Closer, error) { ...@@ -59,7 +59,7 @@ func startLogging(config logConfiguration) (io.Closer, error) {
// In text format, we use a separate logger for access logs // In text format, we use a separate logger for access logs
func getAccessLogger(config logConfiguration) (*log.Logger, io.Closer, error) { func getAccessLogger(config logConfiguration) (*log.Logger, io.Closer, error) {
if config.logFormat != "text" { if config.logFormat != "text" {
return log.StandardLogger(), nil, nil return log.StandardLogger(), ioutil.NopCloser(nil), nil
} }
logFile := config.logFile logFile := config.logFile
......
...@@ -81,9 +81,13 @@ func main() { ...@@ -81,9 +81,13 @@ func main() {
os.Exit(0) os.Exit(0)
} }
log.WithError(run()).Fatal("shutting down")
}
func run() error {
closer, err := startLogging(logConfig) closer, err := startLogging(logConfig)
if err != nil { if err != nil {
log.WithError(err).Fatal("Unable to configure logger") return err
} }
defer closer.Close() defer closer.Close()
...@@ -91,12 +95,12 @@ func main() { ...@@ -91,12 +95,12 @@ func main() {
backendURL, err := parseAuthBackend(*authBackend) backendURL, err := parseAuthBackend(*authBackend)
if err != nil { if err != nil {
log.WithError(err).Fatal("Invalid authBackend") return fmt.Errorf("authBackend: %v", err)
} }
cableBackendURL, err := parseAuthBackend(*cableBackend) cableBackendURL, err := parseAuthBackend(*cableBackend)
if err != nil { if err != nil {
log.WithError(err).Fatal("Invalid cableBackend") return fmt.Errorf("cableBackend: %v", err)
} }
log.WithField("version", Version).WithField("build_time", BuildTime).Print("Starting") log.WithField("version", Version).WithField("build_time", BuildTime).Print("Starting")
...@@ -104,7 +108,7 @@ func main() { ...@@ -104,7 +108,7 @@ func main() {
// Good housekeeping for Unix sockets: unlink before binding // Good housekeeping for Unix sockets: unlink before binding
if *listenNetwork == "unix" { if *listenNetwork == "unix" {
if err := os.Remove(*listenAddr); err != nil && !os.IsNotExist(err) { if err := os.Remove(*listenAddr); err != nil && !os.IsNotExist(err) {
log.WithError(err).Fatal("Failed to remove socket") return err
} }
} }
...@@ -113,32 +117,38 @@ func main() { ...@@ -113,32 +117,38 @@ func main() {
listener, err := net.Listen(*listenNetwork, *listenAddr) listener, err := net.Listen(*listenNetwork, *listenAddr)
syscall.Umask(oldUmask) syscall.Umask(oldUmask)
if err != nil { if err != nil {
log.WithError(err).Fatal("Failed to listen") return fmt.Errorf("main listener: %v", err)
} }
finalErrors := make(chan error)
// The profiler will only be activated by HTTP requests. HTTP // The profiler will only be activated by HTTP requests. HTTP
// requests can only reach the profiler if we start a listener. So by // requests can only reach the profiler if we start a listener. So by
// having no profiler HTTP listener by default, the profiler is // having no profiler HTTP listener by default, the profiler is
// effectively disabled by default. // effectively disabled by default.
if *pprofListenAddr != "" { if *pprofListenAddr != "" {
go func() { l, err := net.Listen("tcp", *pprofListenAddr)
err := http.ListenAndServe(*pprofListenAddr, nil)
if err != nil { if err != nil {
log.WithError(err).Error("Failed to start pprof listener") return fmt.Errorf("pprofListenAddr: %v", err)
} }
}()
go func() { finalErrors <- http.Serve(l, nil) }()
} }
monitoringOpts := []monitoring.Option{monitoring.WithBuildInformation(Version, BuildTime)} monitoringOpts := []monitoring.Option{monitoring.WithBuildInformation(Version, BuildTime)}
if *prometheusListenAddr != "" { if *prometheusListenAddr != "" {
monitoringOpts = append(monitoringOpts, monitoring.WithListenerAddress(*prometheusListenAddr)) l, err := net.Listen("tcp", *prometheusListenAddr)
if err != nil {
return fmt.Errorf("prometheusListenAddr: %v", err)
}
monitoringOpts = append(monitoringOpts, monitoring.WithListener(l))
} }
go func() { go func() {
err := monitoring.Start(monitoringOpts...) // Unlike http.Serve, which always returns a non-nil error,
if err != nil { // monitoring.Start may return nil in which case we should not shut down.
log.WithError(err).Error("Failed to start monitoring") if err := monitoring.Start(monitoringOpts...); err != nil {
finalErrors <- err
} }
}() }()
...@@ -163,7 +173,7 @@ func main() { ...@@ -163,7 +173,7 @@ func main() {
if *configFile != "" { if *configFile != "" {
cfgFromFile, err := config.LoadConfig(*configFile) cfgFromFile, err := config.LoadConfig(*configFile)
if err != nil { if err != nil {
log.WithField("configFile", *configFile).WithError(err).Fatal("Can not load config file") return fmt.Errorf("configFile: %v", err)
} }
cfg.Redis = cfgFromFile.Redis cfg.Redis = cfgFromFile.Redis
...@@ -177,22 +187,19 @@ func main() { ...@@ -177,22 +187,19 @@ func main() {
err = cfg.RegisterGoCloudURLOpeners() err = cfg.RegisterGoCloudURLOpeners()
if err != nil { if err != nil {
log.WithError(err).Fatal("could not load cloud credentials") return fmt.Errorf("register cloud credentials: %v", err)
} }
} }
accessLogger, accessCloser, err := getAccessLogger(logConfig) accessLogger, accessCloser, err := getAccessLogger(logConfig)
if err != nil { if err != nil {
log.WithError(err).Fatal("Unable to configure access logger") return fmt.Errorf("configure access logger: %v", err)
} }
if accessCloser != nil {
defer accessCloser.Close() defer accessCloser.Close()
}
up := wrapRaven(upstream.NewUpstream(cfg, accessLogger)) up := wrapRaven(upstream.NewUpstream(cfg, accessLogger))
err = http.Serve(listener, up) go func() { finalErrors <- http.Serve(listener, up) }()
if err != nil {
log.WithError(err).Fatal("Unable to serve") return <-finalErrors
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment