diff --git a/cleanenv.go b/cleanenv.go index a7dc346..0bca32b 100644 --- a/cleanenv.go +++ b/cleanenv.go @@ -249,7 +249,7 @@ type structMeta struct { description string updatable bool required bool - path []string + path string } // isFieldValueZero determines if fieldValue empty or not @@ -303,10 +303,10 @@ func readStructMetadata(cfgRoot interface{}) ([]structMeta, error) { type cfgNode struct { Val interface{} Prefix string - Path []string + Path string } - cfgStack := []cfgNode{{cfgRoot, "", nil}} + cfgStack := []cfgNode{{cfgRoot, "", ""}} metas := make([]structMeta, 0) for i := 0; i < len(cfgStack); i++ { @@ -347,7 +347,7 @@ func readStructMetadata(cfgRoot interface{}) ([]structMeta, error) { cfgStack = append(cfgStack, cfgNode{ Val: fld.Addr().Interface(), Prefix: sPrefix + prefix, - Path: append(cfgStack[i].Path, fType.Name), + Path: fmt.Sprintf("%s%s.", cfgStack[i].Path, fType.Name), }) continue } diff --git a/cleanenv_test.go b/cleanenv_test.go index ad32d4d..67f7b64 100644 --- a/cleanenv_test.go +++ b/cleanenv_test.go @@ -333,6 +333,9 @@ func TestReadEnvErrors(t *testing.T) { Host string `env:"HOST" env-required:"true"` TTL time.Duration `env:"TTL"` } `env-prefix:"TEST_ERRORS_DATABASE_"` + ThirdStruct struct { + Host string `env:"HOST"` + } `env-prefix:"TEST_ERRORS_THIRD_"` } tests := []struct { @@ -348,7 +351,7 @@ func TestReadEnvErrors(t *testing.T) { cfg: &testEnvErrors{}, errorAs: RequireError{}, errorWant: RequireError{ - FieldPath: []string{"Database"}, + FieldPath: "Database.", FieldName: "Host", EnvName: "TEST_ERRORS_DATABASE_HOST", }, @@ -364,6 +367,7 @@ func TestReadEnvErrors(t *testing.T) { errorWant: ParsingError{ Err: fmt.Errorf("time: invalid duration \"bad-value\""), FieldName: "TTL", + FieldPath: "Database.", EnvName: "TEST_ERRORS_DATABASE_TTL", }, }, diff --git a/errors.go b/errors.go index c072be2..ada6b5c 100644 --- a/errors.go +++ b/errors.go @@ -2,16 +2,15 @@ package cleanenv import ( "fmt" - "strings" ) type RequireError struct { FieldName string - FieldPath []string + FieldPath string EnvName string } -func newRequireError(fieldName string, fieldPath []string, envName string) RequireError { +func newRequireError(fieldName string, fieldPath string, envName string) RequireError { return RequireError{ FieldName: fieldName, FieldPath: fieldPath, @@ -22,18 +21,18 @@ func newRequireError(fieldName string, fieldPath []string, envName string) Requi func (r RequireError) Error() string { return fmt.Sprintf( "field %q is required but the value is not provided", - strings.Join(append(r.FieldPath, r.FieldName), "."), + r.FieldPath+r.FieldName, ) } type ParsingError struct { Err error FieldName string - FieldPath []string + FieldPath string EnvName string } -func newParsingError(fieldName string, fieldPath []string, envName string, err error) ParsingError { +func newParsingError(fieldName string, fieldPath string, envName string, err error) ParsingError { return ParsingError{ FieldName: fieldName, FieldPath: fieldPath, @@ -44,8 +43,8 @@ func newParsingError(fieldName string, fieldPath []string, envName string, err e func (p ParsingError) Error() string { return fmt.Sprintf( - "parsing field %v env %v: %v", - strings.Join(append(p.FieldPath, p.FieldName), "."), + "parsing field %q env %q: %v", + p.FieldPath+p.FieldName, p.EnvName, p.Err, )