Hi, i’m creating a small app in golang and i’m wondering when to use log.Fatal(), panic and just print the error and return the function without panicking.
For example:
//Configuration represents the data that will be read from the yaml config file
type Configuration struct {
Certificate string `yaml:"Certificate"`
Key string `yaml:"Key"`
Hostname string `yaml:"Hostname"`
Port string `yaml:"Port"`
ConnectionString string `yaml:"ConnectionString"`
DbType string `yaml:"DbType"`
}
//SetConfiguration gets configuration from a yaml config file.
func SetConfiguration() *Configuration {
config := new(Configuration)
data, err := ioutil.ReadFile("config/server.yml")
if err != nil {
log.Fatal(err)
}
ok := yaml.Unmarshal(data, config)
if ok != nil {
log.Fatal(err)
}
return config
}
I’m not using golangs logger, so. So I rephrase the question to:
When to print, when to print and exit and when to return with error?
I usually print an error when I either can recover easily or when I can fallback to something else. Eg. I can not reach the database, but I can try again in a couple of milliseconds.
I print and exit when I’m unable to recover. Eg I can not open important configuration files.
I do return when I’m not in the main control loop of the application or when I’m writing library code, as I hate when libraries just print into my precious stdout with weird formatting and without any structure (I’m mostly logging JSON)
As this is a method, I would not panic but return an error and decided in the caller code what to do. If you decide to panic you should rename your method to MustSetConfiguration.
Because structured logging into JSON is a requirement in my area, that’s hard to achieve with the standard logger. Also I find zaps approach very nice when adding arbitrary metadata.