From daadd5a6c367908fe8720997d7d68674cfa41d55 Mon Sep 17 00:00:00 2001 From: Aleksey Zhukov Date: Tue, 14 Mar 2023 14:01:23 +0200 Subject: [PATCH] Add nesting to the panic errors --- di.go | 12 +++++++++++ di_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/di.go b/di.go index b26557f3..fb4ed26d 100644 --- a/di.go +++ b/di.go @@ -102,6 +102,12 @@ func Invoke[T any](i *Injector) (T, error) { } func MustInvoke[T any](i *Injector) T { + defer func() { + if err := recover(); err != nil { + must(fmt.Errorf("invoke service `%s` -> %v", generateServiceName[T](), err)) + } + }() + s, err := Invoke[T](i) must(err) return s @@ -112,6 +118,12 @@ func InvokeNamed[T any](i *Injector, name string) (T, error) { } func MustInvokeNamed[T any](i *Injector, name string) T { + defer func() { + if err := recover(); err != nil { + must(fmt.Errorf("invoke named service `%s` name `%s` -> %v", generateServiceName[T](), name, err)) + } + }() + s, err := InvokeNamed[T](i, name) must(err) return s diff --git a/di_test.go b/di_test.go index a41be9ea..8c712720 100644 --- a/di_test.go +++ b/di_test.go @@ -208,6 +208,37 @@ func TestMustInvoke(t *testing.T) { }) } +func TestMustInvokeNestedPanicError(t *testing.T) { + is := assert.New(t) + + i := New() + + type a struct{} + type c struct{} + + type b struct { + A a + C c + } + + Provide(i, func(i *Injector) (a, error) { + return a{}, nil + }) + + Provide(i, func(i *Injector) (b, error) { + return b{ + A: MustInvoke[a](i), + C: MustInvoke[c](i), + }, nil + }) + + is.PanicsWithError("invoke service `do.b` -> invoke service `do.c` -> DI: could not find service `do.c`, available services: `do.a`, `do.b`", + func() { + MustInvoke[b](i) + }, + ) +} + func TestMustInvokeNamed(t *testing.T) { is := assert.New(t) @@ -231,6 +262,37 @@ func TestMustInvokeNamed(t *testing.T) { }) } +func TestMustInvokeNamedNestedPanicError(t *testing.T) { + is := assert.New(t) + + i := New() + + type a struct{} + type c struct{} + + type b struct { + A a + C c + } + + Provide(i, func(i *Injector) (a, error) { + return a{}, nil + }) + + ProvideNamed(i, "bName", func(i *Injector) (b, error) { + return b{ + A: MustInvoke[a](i), + C: MustInvokeNamed[c](i, "cName"), + }, nil + }) + + is.PanicsWithError("invoke named service `do.b` name `bName` -> invoke named service `do.c` name `cName` -> DI: could not find service `cName`, available services: `do.a`, `bName`", + func() { + MustInvokeNamed[b](i, "bName") + }, + ) +} + func TestShutdown(t *testing.T) { is := assert.New(t)