Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: improve errors #329

Merged
merged 2 commits into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions env.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,11 +550,11 @@ func get(fieldParams FieldParams, opts Options) (val string, err error) {
}

if fieldParams.Required && !exists && len(fieldParams.OwnKey) > 0 {
return "", newEnvVarIsNotSet(fieldParams.Key)
return "", newVarIsNotSetError(fieldParams.Key)
}

if fieldParams.NotEmpty && val == "" {
return "", newEmptyEnvVarError(fieldParams.Key)
return "", newEmptyVarError(fieldParams.Key)
}

if fieldParams.LoadFile && val != "" {
Expand Down
22 changes: 11 additions & 11 deletions env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,8 @@ func TestParsesEnvInnerFailsMultipleErrors(t *testing.T) {
err := Parse(&config{})
isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; parse error on field "Number" of type "int": strconv.ParseInt: parsing "not-a-number": invalid syntax; required environment variable "AGE" is not set`)
isTrue(t, errors.Is(err, ParseError{}))
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
}

func TestParsesEnvInnerNil(t *testing.T) {
Expand Down Expand Up @@ -900,7 +900,7 @@ func TestErrorRequiredNotSet(t *testing.T) {
}
err := Parse(&config{})
isErrorWithMessage(t, err, `env: required environment variable "IS_REQUIRED" is not set`)
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
}

func TestNoErrorNotEmptySet(t *testing.T) {
Expand All @@ -926,7 +926,7 @@ func TestErrorNotEmptySet(t *testing.T) {
}
err := Parse(&config{})
isErrorWithMessage(t, err, `env: environment variable "IS_REQUIRED" should not be empty`)
isTrue(t, errors.Is(err, EmptyEnvVarError{}))
isTrue(t, errors.Is(err, EmptyVarError{}))
}

func TestErrorRequiredAndNotEmptySet(t *testing.T) {
Expand All @@ -936,7 +936,7 @@ func TestErrorRequiredAndNotEmptySet(t *testing.T) {
}
err := Parse(&config{})
isErrorWithMessage(t, err, `env: environment variable "IS_REQUIRED" should not be empty`)
isTrue(t, errors.Is(err, EmptyEnvVarError{}))
isTrue(t, errors.Is(err, EmptyVarError{}))
}

func TestErrorRequiredNotSetWithDefault(t *testing.T) {
Expand Down Expand Up @@ -1016,7 +1016,7 @@ func TestParseUnsetRequireOptions(t *testing.T) {

err := Parse(&cfg)
isErrorWithMessage(t, err, `env: required environment variable "PASSWORD" is not set`)
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
t.Setenv("PASSWORD", "superSecret")
isNoErr(t, Parse(&cfg))

Expand Down Expand Up @@ -1435,7 +1435,7 @@ func TestFileNoParamRequired(t *testing.T) {

err := Parse(&config{})
isErrorWithMessage(t, err, `env: required environment variable "SECRET_KEY" is not set`)
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
}

func TestFileBadFile(t *testing.T) {
Expand Down Expand Up @@ -1525,11 +1525,11 @@ func TestRequiredIfNoDefOption(t *testing.T) {
t.Run("missing", func(t *testing.T) {
err := ParseWithOptions(&cfg, Options{RequiredIfNoDef: true})
isErrorWithMessage(t, err, `env: required environment variable "NAME" is not set; required environment variable "FRUIT" is not set`)
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
t.Setenv("NAME", "John")
err = ParseWithOptions(&cfg, Options{RequiredIfNoDef: true})
isErrorWithMessage(t, err, `env: required environment variable "FRUIT" is not set`)
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
})

t.Run("all set", func(t *testing.T) {
Expand Down Expand Up @@ -1561,7 +1561,7 @@ func TestRequiredIfNoDefNested(t *testing.T) {

err := ParseWithOptions(&cfg, Options{RequiredIfNoDef: true})
isErrorWithMessage(t, err, `env: required environment variable "SERVER_PORT" is not set`)
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
})

t.Run("all set", func(t *testing.T) {
Expand Down Expand Up @@ -2123,7 +2123,7 @@ func TestIssue298ErrorNestedFieldRequiredNotSet(t *testing.T) {
cfg := ComplexConfig{}
err := Parse(&cfg)
isErrorWithMessage(t, err, `env: required environment variable "FOO_0_STR" is not set`)
isTrue(t, errors.Is(err, EnvVarIsNotSetError{}))
isTrue(t, errors.Is(err, VarIsNotSetError{}))
}

func TestIssue320(t *testing.T) {
Expand Down
53 changes: 28 additions & 25 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
// NotStructPtrError
// NoParserError
// NoSupportedTagOptionError
// EnvVarIsNotSetError
// EmptyEnvVarError
// VarIsNotSetError
// EmptyVarError
// LoadFileContentError
// ParseValueError
type AggregateError struct {
Expand Down Expand Up @@ -65,16 +65,14 @@ func (e ParseError) Error() string {
return fmt.Sprintf(`parse error on field "%s" of type "%s": %v`, e.Name, e.Type, e.Err)
}

// The error occurs when pass something that is not a pointer to a Struct to Parse
// The error occurs when pass something that is not a pointer to a struct to Parse
type NotStructPtrError struct{}

func (e NotStructPtrError) Error() string {
return "expected a pointer to a Struct"
}

// This error occurs when there is no parser provided for given type
// Supported types and defaults: https://github.com/caarlos0/env#supported-types-and-defaults
// How to create a custom parser: https://github.com/caarlos0/env#custom-parser-funcs
// This error occurs when there is no parser provided for given type.
type NoParserError struct {
Name string
Type reflect.Type
Expand All @@ -88,9 +86,9 @@ func (e NoParserError) Error() string {
return fmt.Sprintf(`no parser found for field "%s" of type "%s"`, e.Name, e.Type)
}

// This error occurs when the given tag is not supported
// In-built supported tags: "", "file", "required", "unset", "notEmpty", "expand", "envDefault", "envSeparator"
// How to create a custom tag: https://github.com/caarlos0/env#changing-default-tag-name
// This error occurs when the given tag is not supported.
// Built-in supported tags: "", "file", "required", "unset", "notEmpty",
// "expand", "envDefault", and "envSeparator".
type NoSupportedTagOptionError struct {
Tag string
}
Expand All @@ -103,36 +101,43 @@ func (e NoSupportedTagOptionError) Error() string {
return fmt.Sprintf("tag option %q not supported", e.Tag)
}

// This error occurs when the required variable is not set
// Read about required fields: https://github.com/caarlos0/env#required-fields
type EnvVarIsNotSetError struct {
// This error occurs when the required variable is not set.
//
// deprecated: use VarIsNotSetError
type EnvVarIsNotSetError = VarIsNotSetError

// This error occurs when the required variable is not set.
type VarIsNotSetError struct {
Key string
}

func newEnvVarIsNotSet(key string) error {
return EnvVarIsNotSetError{key}
func newVarIsNotSetError(key string) error {
return VarIsNotSetError{key}
}

func (e EnvVarIsNotSetError) Error() string {
func (e VarIsNotSetError) Error() string {
return fmt.Sprintf(`required environment variable %q is not set`, e.Key)
}

// This error occurs when the variable which must be not empty is existing but has an empty value
// Read about not empty fields: https://github.com/caarlos0/env#not-empty-fields
type EmptyEnvVarError struct {
//
// deprecated: use EmptyVarError
type EmptyEnvVarError = EmptyVarError

// This error occurs when the variable which must be not empty is existing but has an empty value
type EmptyVarError struct {
Key string
}

func newEmptyEnvVarError(key string) error {
return EmptyEnvVarError{key}
func newEmptyVarError(key string) error {
return EmptyVarError{key}
}

func (e EmptyEnvVarError) Error() string {
func (e EmptyVarError) Error() string {
return fmt.Sprintf("environment variable %q should not be empty", e.Key)
}

// This error occurs when it's impossible to load the value from the file
// Read about From file feature: https://github.com/caarlos0/env#from-file
// This error occurs when it's impossible to load the value from the file.
type LoadFileContentError struct {
Filename string
Key string
Expand All @@ -147,9 +152,7 @@ func (e LoadFileContentError) Error() string {
return fmt.Sprintf(`could not load content of file "%s" from variable %s: %v`, e.Filename, e.Key, e.Err)
}

// This error occurs when it's impossible to convert value using given parser
// Supported types and defaults: https://github.com/caarlos0/env#supported-types-and-defaults
// How to create a custom parser: https://github.com/caarlos0/env#custom-parser-funcs
// This error occurs when it's impossible to convert value using given parser.
type ParseValueError struct {
Msg string
Err error
Expand Down
4 changes: 2 additions & 2 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ func ExampleParse_errorHandling() {

var cfg Config
if err := Parse(&cfg); err != nil {
if errors.Is(err, EmptyEnvVarError{}) {
if errors.Is(err, EmptyVarError{}) {
fmt.Println("oopsie")
}
aggErr := AggregateError{}
Expand All @@ -440,7 +440,7 @@ func ExampleParse_errorHandling() {
// EmptyEnvVarError
// LoadFileContentError
// ParseValueError
case EmptyEnvVarError:
case EmptyVarError:
fmt.Println("daisy")
default:
fmt.Printf("Unknown error type %v", v)
Expand Down
Loading