Skip to content

Commit

Permalink
feat: improve errors messages
Browse files Browse the repository at this point in the history
  • Loading branch information
samber committed Dec 31, 2023
1 parent be00827 commit 59acf30
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 15 deletions.
4 changes: 3 additions & 1 deletion di.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ func InvokeStruct[T any](i Injector) (*T, error) {
return nil, fmt.Errorf("DI: not a struct")
}

err := invokeByTags(i, value)
structName := inferServiceName[T]()

err := invokeByTags(i, structName, value)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion di_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ func TestInvokeStruct(t *testing.T) {
EagerTest *int `do:"*github.com/samber/do/v2.eagerTest"`
}
test7, err := InvokeStruct[namedDependencyButTypeMismatch](i)
is.Equal("DI: field 'EagerTest' is not assignable to service *github.com/samber/do/v2.eagerTest", err.Error())
is.Equal("DI: field `github.com/samber/do/v2.namedDependencyButTypeMismatch.EagerTest` is not assignable to service *github.com/samber/do/v2.eagerTest", err.Error())
is.Nil(test7)

// use a custom tag
Expand Down
6 changes: 3 additions & 3 deletions invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func invokeByGenericType[T any](i Injector) (T, error) {
}

// invokeByTag looks for a service by its tag.
func invokeByTags(i Injector, structValue reflect.Value) error {
func invokeByTags(i Injector, structName string, structValue reflect.Value) error {
injector := getInjectorOrDefault(i)

// Ensure that servicePtr is a pointer to a struct
Expand All @@ -186,7 +186,7 @@ func invokeByTags(i Injector, structValue reflect.Value) error {
}

if !fieldValue.CanAddr() {
return fmt.Errorf("DI: field is not addressable %s", field.Name)
return fmt.Errorf("DI: field is not addressable `%s.%s`", structName, field.Name)
}

if !fieldValue.CanSet() {
Expand All @@ -208,7 +208,7 @@ func invokeByTags(i Injector, structValue reflect.Value) error {

// Should be check before invocation, because we just built something that is not assignable to the field.
if !fieldValue.Type().AssignableTo(dependencyValue.Type()) {
return fmt.Errorf("DI: field '%s' is not assignable to service %s", field.Name, serviceName)
return fmt.Errorf("DI: field `%s.%s` is not assignable to service %s", structName, field.Name, serviceName)
}

// Should not panic, since we checked CanAddr() and CanSet() earlier.
Expand Down
20 changes: 10 additions & 10 deletions invoke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,19 +243,19 @@ func TestInvokeByTags(t *testing.T) {
ProvideValue(i, &eagerTest{foobar: "foobar"})

// no dependencies
err := invokeByTags(i, reflect.ValueOf(&eagerTest{}))
err := invokeByTags(i, "*myStruct", reflect.ValueOf(&eagerTest{}))
is.Nil(err)

// not pointer
err = invokeByTags(i, reflect.ValueOf(eagerTest{}))
err = invokeByTags(i, "*myStruct", reflect.ValueOf(eagerTest{}))
is.Equal("DI: not a pointer", err.Error())

// exported field - generic type
type hasExportedEagerTestDependency struct {
EagerTest *eagerTest `do:""`
}
test1 := hasExportedEagerTestDependency{}
err = invokeByTags(i, reflect.ValueOf(&test1))
err = invokeByTags(i, "*myStruct", reflect.ValueOf(&test1))
is.Nil(err)
is.Equal("foobar", test1.EagerTest.foobar)

Expand All @@ -264,7 +264,7 @@ func TestInvokeByTags(t *testing.T) {
eagerTest *eagerTest `do:""`
}
test2 := hasNonExportedEagerTestDependency{}
err = invokeByTags(i, reflect.ValueOf(&test2))
err = invokeByTags(i, "*myStruct", reflect.ValueOf(&test2))
is.Nil(err)
is.Equal("foobar", test2.eagerTest.foobar)

Expand All @@ -273,15 +273,15 @@ func TestInvokeByTags(t *testing.T) {
eagerTest *hasNonExportedEagerTestDependency `do:""` //nolint:unused
}
test3 := dependencyNotFound{}
err = invokeByTags(i, reflect.ValueOf(&test3))
err = invokeByTags(i, "*myStruct", reflect.ValueOf(&test3))
is.Equal(serviceNotFound(i, []string{inferServiceName[*hasNonExportedEagerTestDependency]()}).Error(), err.Error())

// use tag
type namedDependency struct {
eagerTest *eagerTest `do:"int"` //nolint:unused
}
test4 := namedDependency{}
err = invokeByTags(i, reflect.ValueOf(&test4))
err = invokeByTags(i, "*myStruct", reflect.ValueOf(&test4))
is.Equal(serviceNotFound(i, []string{inferServiceName[int]()}).Error(), err.Error())

// named service
Expand All @@ -290,7 +290,7 @@ func TestInvokeByTags(t *testing.T) {
EagerTest int `do:"foobar"`
}
test5 := namedService{}
err = invokeByTags(i, reflect.ValueOf(&test5))
err = invokeByTags(i, "*myStruct", reflect.ValueOf(&test5))
is.Nil(err)
is.Equal(42, test5.EagerTest)

Expand All @@ -299,8 +299,8 @@ func TestInvokeByTags(t *testing.T) {
EagerTest *int `do:"*github.com/samber/do/v2.eagerTest"`
}
test6 := namedDependencyButTypeMismatch{}
err = invokeByTags(i, reflect.ValueOf(&test6))
is.Equal("DI: field 'EagerTest' is not assignable to service *github.com/samber/do/v2.eagerTest", err.Error())
err = invokeByTags(i, "*myStruct", reflect.ValueOf(&test6))
is.Equal("DI: field `*myStruct.EagerTest` is not assignable to service *github.com/samber/do/v2.eagerTest", err.Error())

// use a custom tag
i = NewWithOpts(&InjectorOpts{StructTagKey: "hello"})
Expand All @@ -309,7 +309,7 @@ func TestInvokeByTags(t *testing.T) {
EagerTest int `hello:"foobar"`
}
test7 := namedServiceWithCustomTag{}
err = invokeByTags(i, reflect.ValueOf(&test7))
err = invokeByTags(i, "*myStruct", reflect.ValueOf(&test7))
is.Nil(err)
is.Equal(42, test7.EagerTest)
}
Expand Down

0 comments on commit 59acf30

Please sign in to comment.