Skip to content

Commit

Permalink
Include trace for fx.Provide(return fx.Annotated)
Browse files Browse the repository at this point in the history
This changes error reporting to include a stack trace of the
`fx.Provide()` call site when failing because the user provided a
function that returns an `fx.Annotated` instead of providing an
`fx.Annotated` directly.
  • Loading branch information
abhinav committed Nov 20, 2019
1 parent 14ba556 commit 4137f84
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
16 changes: 15 additions & 1 deletion annotated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/fx"
"go.uber.org/fx/fxtest"
)
Expand Down Expand Up @@ -83,7 +84,20 @@ func TestAnnotatedWrongUsage(t *testing.T) {
),
fx.Populate(&in),
)
assert.Contains(t, app.Err().Error(), "fx.Annotated should be passed to fx.Provide directly", "expected error when return types were annotated")

err := app.Err()
require.Error(t, err)

// Example:
// fx.Annotated should be passed to fx.Provide directly, it should not be returned by the constructor: fx.Provide received go.uber.org/fx_test.TestAnnotatedWrongUsage.func2.1() from:
// go.uber.org/fx_test.TestAnnotatedWrongUsage.func2
// /.../fx/annotated_test.go:76
// testing.tRunner
// /.../go/1.13.3/libexec/src/testing/testing.go:909
assert.Contains(t, err.Error(), "fx.Annotated should be passed to fx.Provide directly, it should not be returned by the constructor")
assert.Contains(t, err.Error(), "fx.Provide received go.uber.org/fx_test.TestAnnotatedWrongUsage")
assert.Contains(t, err.Error(), "go.uber.org/fx_test.TestAnnotatedWrongUsage")
assert.Contains(t, err.Error(), "/fx/annotated_test.go")
})

t.Run("Result Type", func(t *testing.T) {
Expand Down
6 changes: 5 additions & 1 deletion app.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,11 @@ func (app *App) provide(p provide) {
t := ft.Out(i)

if t == reflect.TypeOf(Annotated{}) {
app.err = fmt.Errorf("fx.Annotated should be passed to fx.Provide directly, it should not be returned by the constructor: fx.Provide received %v", constructor)
app.err = fmt.Errorf(
"fx.Annotated should be passed to fx.Provide directly, "+
"it should not be returned by the constructor: "+
"fx.Provide received %v from:\n%+v",
fxreflect.FuncName(constructor), p.Stack)
return
}
}
Expand Down

0 comments on commit 4137f84

Please sign in to comment.