From 1ca3a1af42ebaa76fbc7d0e3fbe6570c2fd3dd78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 19 Dec 2023 22:45:05 +0000 Subject: [PATCH] cmd/node: make loadConfig directly log any errors The function already logged at the info level, so do the same for any messages like "creating config file". For any errors that means we can't continue, log at the fatal level directly rather than returning an error. This is a function used only by the main function, so that's fine. It also keeps our code easier to follow. We also make errors such as "failed to read config", "failed to unmarshal config", and "failed to write config" fatal, so as to not log them as warnings and silently continue. If there are any such errors, the user likely wants to correct them. --- cmd/node/main.go | 59 ++++++++++++------------------------------------ config/config.go | 10 -------- 2 files changed, 14 insertions(+), 55 deletions(-) diff --git a/cmd/node/main.go b/cmd/node/main.go index f47ffa829..1e3ef7691 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -110,19 +110,14 @@ func (p pflagValue) HasChanged() bool { return p.flag.Changed } func (p pflagValue) ValueString() string { return p.flag.Value.String() } func (p pflagValue) ValueType() string { return p.flag.Value.Type() } -// newConfig creates a new config object and loads the stored configuration file -func newConfig() (*config.Config, config.Error) { - var cfgError config.Error +// loadConfig creates a new config object and loads the stored configuration file +func loadConfig() *config.Config { conf := &config.Config{} // get current user home dir home, err := os.UserHomeDir() if err != nil { - cfgError = config.Error{ - Critical: true, - Message: fmt.Sprintf("cannot get user home directory with error: %s", err), - } - return nil, cfgError + log.Fatal(err) } // CLI flags will be used if something fails from this point @@ -252,37 +247,27 @@ func newConfig() (*config.Config, config.Error) { // check if config file exists _, err = os.Stat(conf.DataDir + "/vocdoni.yml") if os.IsNotExist(err) { - cfgError = config.Error{ - Message: fmt.Sprintf("creating new config file in %s", conf.DataDir), - } + log.Infof("creating new config file in %s", conf.DataDir) // creating config folder if not exists err = os.MkdirAll(conf.DataDir, os.ModePerm) if err != nil { - cfgError = config.Error{ - Message: fmt.Sprintf("cannot create data directory: %s", err), - } + log.Fatalf("cannot create data directory: %s", err) } // create config file if not exists if err := viper.SafeWriteConfig(); err != nil { - cfgError = config.Error{ - Message: fmt.Sprintf("cannot write config file into config dir: %s", err), - } + log.Fatalf("cannot write config file into config dir: %s", err) } } else { // read config file err = viper.ReadInConfig() if err != nil { - cfgError = config.Error{ - Message: fmt.Sprintf("cannot read loaded config file in %s: %s", conf.DataDir, err), - } + log.Fatalf("cannot read loaded config file in %s: %s", conf.DataDir, err) } } err = viper.Unmarshal(&conf) if err != nil { - cfgError = config.Error{ - Message: fmt.Sprintf("cannot unmarshal loaded config file: %s", err), - } + log.Fatalf("cannot unmarshal loaded config file: %s", err) } if conf.SigningKey == "" { @@ -290,10 +275,7 @@ func newConfig() (*config.Config, config.Error) { signer := ethereum.NewSignKeys() err = signer.Generate() if err != nil { - cfgError = config.Error{ - Message: fmt.Sprintf("cannot generate signing key: %s", err), - } - return conf, cfgError + log.Fatalf("cannot generate signing key: %s", err) } _, priv := signer.HexString() viper.Set("signingKey", priv) @@ -313,13 +295,11 @@ func newConfig() (*config.Config, config.Error) { if flagSaveConfig { viper.Set("saveConfig", false) if err := viper.WriteConfig(); err != nil { - cfgError = config.Error{ - Message: fmt.Sprintf("cannot overwrite config file into config dir: %s", err), - } + log.Fatalf("cannot overwrite config file into config dir: %s", err) } } - return conf, cfgError + return conf } func main() { @@ -328,10 +308,8 @@ func main() { fmt.Fprintf(os.Stderr, "vocdoni version %q\n", internal.Version) // creating config and init logger - conf, cfgErr := newConfig() - if conf == nil { - log.Fatal("cannot read configuration") - } + conf := loadConfig() + var errorOutput io.Writer if path := conf.LogErrorFile; path != "" { f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644) @@ -345,6 +323,7 @@ func main() { // Once the logger has been initialized. log.Infof("using file %s for logging warning and errors", path) } + log.Debugf("loaded config %+v", *conf) // Check if we need to create a vochain genesis file with validators and exit. if flagVochainCreateGenesis != "" { @@ -363,16 +342,6 @@ func main() { return } - // Check if errors during config creation and determine if Critical. - log.Debugf("initializing config %+v", *conf) - if cfgErr.Critical && cfgErr.Message != "" { - log.Fatalf("critical error loading config: %s", cfgErr.Message) - } else if !cfgErr.Critical && cfgErr.Message != "" { - log.Warnf("non-critical error loading config: %s", cfgErr.Message) - } else if !cfgErr.Critical && cfgErr.Message == "" { - log.Infof("config file loaded successfully. Reminder: CLI flags have preference") - } - // Overwrite the default path to download the zksnarks circuits artifacts // using the global datadir as parent folder. circuit.BaseDir = filepath.Join(conf.DataDir, "zkCircuits") diff --git a/config/config.go b/config/config.go index d8a7bf0ef..957e531ff 100644 --- a/config/config.go +++ b/config/config.go @@ -142,13 +142,3 @@ type MetricsCfg struct { Enabled bool RefreshInterval int } - -// TODO(mvdan): replace with a special error type - -// Error helps to handle better config errors on startup -type Error struct { - // Critical indicates if the error encountered is critical and the app must be stopped - Critical bool - // Message error message - Message string -}