From 59acf307ffd03e0924b5d68c65bc4fe109007f3e Mon Sep 17 00:00:00 2001 From: Samuel Berthe Date: Sun, 31 Dec 2023 01:05:54 +0100 Subject: [PATCH] feat: improve errors messages --- di.go | 4 +++- di_test.go | 2 +- invoke.go | 6 +++--- invoke_test.go | 20 ++++++++++---------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/di.go b/di.go index 3610947..21dd306 100644 --- a/di.go +++ b/di.go @@ -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 } diff --git a/di_test.go b/di_test.go index 16d6d49..acc90c1 100644 --- a/di_test.go +++ b/di_test.go @@ -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 diff --git a/invoke.go b/invoke.go index a1693de..270bf58 100644 --- a/invoke.go +++ b/invoke.go @@ -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 @@ -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() { @@ -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. diff --git a/invoke_test.go b/invoke_test.go index 4df7cd3..61e9212 100644 --- a/invoke_test.go +++ b/invoke_test.go @@ -243,11 +243,11 @@ 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 @@ -255,7 +255,7 @@ func TestInvokeByTags(t *testing.T) { 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) @@ -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) @@ -273,7 +273,7 @@ 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 @@ -281,7 +281,7 @@ func TestInvokeByTags(t *testing.T) { 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 @@ -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) @@ -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"}) @@ -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) }