diff --git a/dig_test.go b/dig_test.go index 2709466a..4761f83b 100644 --- a/dig_test.go +++ b/dig_test.go @@ -2417,6 +2417,30 @@ func testProvideFailures(t *testing.T, dryRun bool) { assert.Contains(t, err.Error(), "cannot provide io.Reader") assert.Contains(t, err.Error(), "already provided") }) + + t.Run("error should refer to location given by LocationForPC ProvideOption", func(t *testing.T) { + c := digtest.New(t) + type A struct{ idx int } + type ret struct { + dig.Out + + A1 A // same type A provided twice + A2 A + } + + locationFn := func() {} + + err := c.Provide(func() ret { + return ret{ + A1: A{idx: 1}, + A2: A{idx: 2}, + } + }, dig.LocationForPC(reflect.ValueOf(locationFn).Pointer())) + require.Error(t, err, "provide must return error") + dig.AssertErrorMatches(t, err, + `cannot provide function "go.uber.org/dig_test".testProvideFailures.func\d+.1`, + ) + }) } func TestInvokeFailures(t *testing.T) { @@ -3515,6 +3539,20 @@ func TestEndToEndSuccessWithAliases(t *testing.T) { ) }) + t.Run("duplicate provide with LocationForPC", func(t *testing.T) { + c := digtest.New(t) + c.RequireProvide(func(x int) float64 { + return testStruct{}.TestMethod(x) + }, dig.LocationForPC(reflect.TypeOf(testStruct{}).Method(0).Func.Pointer())) + err := c.Provide(func(x int) float64 { + return testStruct{}.TestMethod(x) + }, dig.LocationForPC(reflect.TypeOf(testStruct{}).Method(0).Func.Pointer())) + + require.Error(t, err) + require.Contains(t, err.Error(), `cannot provide function "go.uber.org/dig_test".testStruct.TestMethod`) + require.Contains(t, err.Error(), `already provided by "go.uber.org/dig_test".testStruct.TestMethod`) + }) + t.Run("named instances", func(t *testing.T) { c := digtest.New(t) type A1 struct{ s string } diff --git a/provide.go b/provide.go index a7066370..3f5937eb 100644 --- a/provide.go +++ b/provide.go @@ -417,8 +417,15 @@ func (s *Scope) Provide(constructor interface{}, opts ...ProvideOption) error { } if err := s.provide(constructor, options); err != nil { + var errFunc *digreflect.Func + if options.Location == nil { + errFunc = digreflect.InspectFunc(constructor) + } else { + errFunc = options.Location + } + return errProvide{ - Func: digreflect.InspectFunc(constructor), + Func: errFunc, Reason: err, } }