Skip to content

Commit

Permalink
Make provide's errors more expressive for fx.Annotate-ed functions (#844
Browse files Browse the repository at this point in the history
)

* Make provide's errors more expressive for fx.Annotate-ed functions

Because of the use of reflection in fx.Annotate, the error
messages for provide tend to refer to the annotated function as
`"reflect".makeFuncStub` which is not helpful for debugging.

This change updates error messages that previously looked like:
```
Failed: cannot provide function "reflect".makeFuncStub (/usr/local/go/src/reflect/asm_arm64.s:12):
cannot provide *fx_test.Logger from [0].Field0: already provided by "reflect".makeFuncStub
(/usr/local/go/src/reflect/asm_arm64.s:12)
```

To looking like this:
```
Failed: cannot provide function "reflect".makeFuncStub (/usr/local/go/src/reflect/asm_amd64.s:12):
cannot provide *fx_test.Logger from [0].Field0: already provided by "go.uber.org/fx_test".TestAnnotate.func1
(/gocode/src/github.com/uber-go/fx/annotated_test.go:515)
```

WIP: Planning on making a future fix that gives a more
readable name to the first function which still is referred to
as "reflect".makeFuncStub after this change.

* Switch to storing ptr value instead of ProvideOption

Co-authored-by: Moises Vega <moises.vega@gmail.com>

* Switch to storing ptr value instead of ProvideOption

Co-authored-by: Moises Vega <moises.vega@gmail.com>

* Switch to storing ptr value instead of ProvideOption

Co-authored-by: Moises Vega <moises.vega@gmail.com>

* Update annotated_test.go test naming

Co-authored-by: Moises Vega <moises.vega@gmail.com>

* Fix lint issue

Co-authored-by: Moises Vega <moises.vega@gmail.com>
Co-authored-by: Sung Yoon Whang <sungyoon@uber.com>
  • Loading branch information
3 people committed Feb 22, 2022
1 parent 15dc60c commit 7bb5b40
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 0 deletions.
2 changes: 2 additions & 0 deletions annotated.go
Expand Up @@ -264,6 +264,7 @@ type annotated struct {
ParamTags []string
ResultTags []string
As [][]reflect.Type
FuncPtr uintptr
}

func (ann annotated) String() string {
Expand Down Expand Up @@ -302,6 +303,7 @@ func (ann *annotated) Build() (interface{}, error) {

newFnType := reflect.FuncOf(paramTypes, resultTypes, false)
origFn := reflect.ValueOf(ann.Target)
ann.FuncPtr = origFn.Pointer()
newFn := reflect.MakeFunc(newFnType, func(args []reflect.Value) []reflect.Value {
args = remapParams(args)
var results []reflect.Value
Expand Down
16 changes: 16 additions & 0 deletions annotated_test.go
Expand Up @@ -787,6 +787,22 @@ func TestAnnotate(t *testing.T) {
defer app.RequireStart().RequireStop()
})

t.Run("provide an already provided function using Annotate", func(t *testing.T) {
t.Parallel()

app := NewForTest(t,
fx.Provide(fx.Annotate(newA, fx.ResultTags(`name:"a"`))),
fx.Provide(fx.Annotate(newA, fx.ResultTags(`name:"a"`))),
fx.Invoke(
fx.Annotate(newB, fx.ParamTags(`name:"a"`)),
),
)
err := app.Err()
require.Error(t, err)
assert.Contains(t, err.Error(), "already provided")
assert.Contains(t, err.Error(), "\"go.uber.org/fx_test\".TestAnnotate.func1")
})

t.Run("specify more ParamTags than Params", func(t *testing.T) {
t.Parallel()

Expand Down
1 change: 1 addition & 0 deletions provide.go
Expand Up @@ -109,6 +109,7 @@ func runProvide(c container, p provide, opts ...dig.ProvideOption) error {
return fmt.Errorf("fx.Provide(%v) from:\n%+vFailed: %v", constructor, p.Stack, err)
}

opts = append(opts, dig.LocationForPC(constructor.FuncPtr))
if err := c.Provide(ctor, opts...); err != nil {
return fmt.Errorf("fx.Provide(%v) from:\n%+vFailed: %v", constructor, p.Stack, err)
}
Expand Down

0 comments on commit 7bb5b40

Please sign in to comment.