diff --git a/app/app.go b/app/app.go index ecdc5995..947000b9 100644 --- a/app/app.go +++ b/app/app.go @@ -23,10 +23,11 @@ var ( ) var ( - log = logger.NewNamed("app") - StopDeadline = time.Minute - StopWarningAfter = time.Second * 10 - StartWarningAfter = time.Second * 10 + log = logger.NewNamed("app") + StopDeadline = time.Minute + StopWarningAfter = time.Second * 10 + StartWarningAfter = time.Second * 10 + ErrComponentNotFound = errors.New("component not found") ) // Component is a minimal interface for a common app.Component @@ -179,22 +180,30 @@ func (app *App) MustComponent(name string) Component { return s } -// MustComponent - generic version of app.MustComponent -func MustComponent[i any](app *App) i { +func GetComponent[t any](app *App) (t, error) { app.mu.RLock() defer app.mu.RUnlock() + var empty t current := app for current != nil { for _, s := range current.components { - if v, ok := s.(i); ok { + if v, ok := s.(t); ok { app.onComponent(s) - return v + return v, nil } } current = current.parent } - empty := new(i) - panic(fmt.Errorf("component with interface %T is not found", empty)) + return empty, ErrComponentNotFound +} + +// MustComponent - generic version of app.MustComponent +func MustComponent[t any](app *App) t { + component, err := GetComponent[t](app) + if err != nil { + panic(fmt.Errorf("component with interface %T is not found", new(t))) + } + return component } // ComponentNames returns all registered names