refactor: better naming, return original error for finder

This commit is contained in:
Matthew Coleman
2025-10-08 12:00:40 +02:00
committed by Márk Sági-Kazár
parent 2d525ac880
commit b9dfcc5b9e
4 changed files with 44 additions and 39 deletions
+32 -26
View File
@@ -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 */
+2 -7
View File
@@ -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) {
+1 -1
View File
@@ -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 {
+8 -4
View File
@@ -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