diff --git a/errors.go b/errors.go index 1745ac5..4fee348 100644 --- a/errors.go +++ b/errors.go @@ -4,54 +4,60 @@ import ( "fmt" ) +/* File look-up errors */ -// FileLookupError is returned when Viper cannot resolve a configuration file, -// either because a file does not exists or because it cannot find any file matching the criteria. +// FileLookupError is returned when Viper cannot resolve a configuration file. +// +// This is meant to be a common interface for all file look-up errors, occurring either because a +// file does not exist or because it cannot find any file matching finder criteria. type FileLookupError interface { error - + fileLookup() } -// ConfigFileNotFoundFromFinderError denotes failing to find a configuration file. -type ConfigFileNotFoundFromFinderError struct { - name, locations string +// ConfigFileNotFoundError denotes failing to find a configuration file from a search. +// +// Deprecated: This is wrapped by FileNotFoundFromSearchError, which should be used instead. +type ConfigFileNotFoundError struct { + name string + locations []string } -// Error returns the formatted configuration error. -func (fnfe ConfigFileNotFoundFromFinderError) Error() string { - message := fmt.Sprintf("Config file %q Not Found", fnfe.name) - if fnfe.locations != "" { - message += fmt.Sprintf(" in %q", fnfe.locations) +// Error returns the formatted error. +func (fnfe ConfigFileNotFoundError) Error() string { + message := fmt.Sprintf("File %q Not Found", fnfe.name) + if len(fnfe.locations) != 0 { + message += fmt.Sprintf(" in %v", fnfe.locations) } return message } -func (fnfe ConfigFileNotFoundFromFinderError) Name() string { - return fnfe.name +// Unwraps to FileNotFoundFromSearchError. +func (fnfe ConfigFileNotFoundError) Unwrap() error { + return FileNotFoundFromSearchError{err: fnfe} } -func (fnfe ConfigFileNotFoundFromFinderError) Locations() string { - return fnfe.locations +// FileNotFoundFromSearchError denotes failing to find a configuration file from a search. +// Wraps ConfigFileNotFoundError. +type FileNotFoundFromSearchError struct { + err ConfigFileNotFoundError } -// ConfigFileNotFoundFromReadError denotes failing to find a specific configuration file. +// Error returns the formatted error. +func (fnfe FileNotFoundFromSearchError) Error() string { + return fnfe.err.Error() +} + +// FileNotFoundError denotes failing to find a specific configuration file. type FileNotFoundError struct { path string } -// Error returns the formatted configuration error. -func (fnfe ConfigFileNotFoundFromReadError) Error() string { - return fmt.Sprintf("Config file %q Not Found", fnfe.name) -} - -func (fnfe ConfigFileNotFoundFromReadError) Name() string { - return fnfe.name -} - -func (fnfe ConfigFileNotFoundFromReadError) Locations() string { - return "" +// Error returns the formatted error. +func (fnfe FileNotFoundError) Error() string { + return fmt.Sprintf("File %q Not Found", fnfe.path) } /* Other error types */ diff --git a/file.go b/file.go index a3c2e25..d51f57d 100644 --- a/file.go +++ b/file.go @@ -1,7 +1,6 @@ package viper import ( - "fmt" "os" "path/filepath" @@ -50,9 +49,7 @@ func (v *Viper) findConfigFileWithFinder(finder Finder) (string, error) { } if len(results) == 0 { - return "", ConfigFileNotFoundFromFinderError{ - name: v.configName, locations: fmt.Sprintf("%s", v.configPaths), - } + return "", ConfigFileNotFoundError{name: v.configName, locations: v.configPaths} } // We call clean on the final result to ensure that the path is in its canonical form. @@ -71,9 +68,7 @@ func (v *Viper) findConfigFileOld() (string, error) { return file, nil } } - return "", ConfigFileNotFoundFromFinderError{ - name: v.configName, locations: fmt.Sprintf("%s", v.configPaths), - } + return "", ConfigFileNotFoundError{name: v.configName, locations: v.configPaths} } func (v *Viper) searchInPath(in string) (filename string) { diff --git a/viper.go b/viper.go index 6aa3169..f84fa02 100644 --- a/viper.go +++ b/viper.go @@ -1495,7 +1495,7 @@ func (v *Viper) ReadInConfig() error { return err } if !exists { - return ConfigFileNotFoundFromReadError{name: filename} + return FileNotFoundError{path: filename} } file, err := afero.ReadFile(v.fs, filename) if err != nil { diff --git a/viper_test.go b/viper_test.go index 0ad07f4..441a97c 100644 --- a/viper_test.go +++ b/viper_test.go @@ -1573,7 +1573,7 @@ func TestReadConfigWithSetConfigFile(t *testing.T) { assert.Equal(t, 45000, v.GetInt("hello.pop")) } -func TestWrongConfigWithSetConfigFileNotFound(t *testing.T) { +func TestWrongConfigWithFileNotFound(t *testing.T) { _, config := initDirs(t) v := New() @@ -1583,7 +1583,7 @@ func TestWrongConfigWithSetConfigFileNotFound(t *testing.T) { v.SetConfigFile(`whatareyoutalkingabout.yaml`) err := v.ReadInConfig() - assert.IsType(t, ConfigFileNotFoundFromReadError{}, err) + assert.ErrorAs(t, err, &FileNotFoundError{}) // Even though config did not load and the error might have // been ignored by the client, the default still loads @@ -1669,7 +1669,9 @@ func TestWrongDirsSearchNotFound(t *testing.T) { v.AddConfigPath(`thispathaintthere`) err := v.ReadInConfig() - assert.IsType(t, ConfigFileNotFoundFromFinderError{name: "", locations: ""}, err) + // It matches both types of errors. + assert.ErrorAs(t, err, &ConfigFileNotFoundError{}) + assert.ErrorAs(t, err, &FileNotFoundFromSearchError{}) // Even though config did not load and the error might have // been ignored by the client, the default still loads @@ -1687,7 +1689,9 @@ func TestWrongDirsSearchNotFoundForMerge(t *testing.T) { v.AddConfigPath(`thispathaintthere`) err := v.MergeInConfig() - assert.Equal(t, reflect.TypeOf(ConfigFileNotFoundFromFinderError{name: "", locations: ""}), reflect.TypeOf(err)) + // It matches both types of errors. + assert.ErrorAs(t, err, &ConfigFileNotFoundError{}) + assert.ErrorAs(t, err, &FileNotFoundFromSearchError{}) // Even though config did not load and the error might have // been ignored by the client, the default still loads