diff --git a/viper.go b/viper.go index 5d26730..7f87f04 100644 --- a/viper.go +++ b/viper.go @@ -1941,17 +1941,22 @@ func (v *Viper) getConfigFile() (string, error) { return v.configFile, nil } -func (v *Viper) searchInPath(in string) (filename string) { +func (v *Viper) searchInPath(in string) (filename string, err error) { + var lastError error jww.DEBUG.Println("Searching for config in ", in) for _, ext := range SupportedExts { jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext)) - if b, _ := exists(v.fs, filepath.Join(in, v.configName+"."+ext)); b { + b, err := exists(v.fs, filepath.Join(in, v.configName+"."+ext)) + fmt.Printf("%s %t %s\n", filepath.Join(in, v.configName+"."+ext), b, err) + if err != nil { + lastError = err + } else if b { jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext)) - return filepath.Join(in, v.configName+"."+ext) + return filepath.Join(in, v.configName+"."+ext), nil } } - return "" + return "", lastError } // Search all configPaths for any config file. @@ -1959,13 +1964,23 @@ func (v *Viper) searchInPath(in string) (filename string) { func (v *Viper) findConfigFile() (string, error) { jww.INFO.Println("Searching for config in ", v.configPaths) + var lastError error for _, cp := range v.configPaths { - file := v.searchInPath(cp) + file, err := v.searchInPath(cp) if file != "" { return file, nil } + if err != nil { + lastError = err + } } - return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} + + // If there was no more-specific error, assume this was a not-found error + if lastError == nil { + lastError = ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} + } + + return "", lastError } // Debug prints all configuration registries for debugging diff --git a/viper_test.go b/viper_test.go index 8bbba76..2016561 100644 --- a/viper_test.go +++ b/viper_test.go @@ -8,6 +8,7 @@ package viper import ( "bytes" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -1018,6 +1019,31 @@ func TestWrongDirsSearchNotFound(t *testing.T) { assert.Equal(t, `default`, v.GetString(`key`)) } +func TestNoPermissionDirs(t *testing.T) { + tmpdir := t.TempDir() + + v := New() + v.SetDefault(`key`, `default`) + + // Make an fs with an un-readable /directory + v.fs = afero.NewBasePathFs(afero.NewOsFs(), tmpdir) + err := v.fs.Mkdir("/directory", 000) + if err != nil { + t.Fatalf("Error from fs.Mkdir: %v", err) + } + + v.AddConfigPath("/directory") + err = v.ReadInConfig() + + if !errors.Is(err, os.ErrPermission) { + t.Fatalf("error should have been a permissions error") + } + + // Even though config did not load and the error might have + // been ignored by the client, the default still loads + assert.Equal(t, `default`, v.GetString(`key`)) +} + func TestWrongDirsSearchNotFoundForMerge(t *testing.T) { _, config, cleanup := initDirs(t)