From 4050f2b38f2a030b68e865daebf462674adcb625 Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 21 Sep 2024 12:00:07 +0200 Subject: [PATCH 1/3] Tariffs: swallow startup errors --- cmd/setup.go | 18 +++++++++++++++++- tariff/wrapper.go | 43 +++++++++++++++++++++++++++++++++++++++++++ vehicle/wrapper.go | 14 +------------- 3 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 tariff/wrapper.go diff --git a/cmd/setup.go b/cmd/setup.go index e096882804..f54f886a72 100644 --- a/cmd/setup.go +++ b/cmd/setup.go @@ -760,12 +760,28 @@ func configureMessengers(conf globalconfig.Messaging, vehicles push.Vehicles, va return messageChan, nil } +func tariffInstance(name string, conf config.Typed) (api.Tariff, error) { + instance, err := tariff.NewFromConfig(conf.Type, conf.Other) + if err != nil { + var ce *util.ConfigError + if errors.As(err, &ce) { + return nil, err + } + + // wrap non-config tariff errors to prevent fatals + log.ERROR.Printf("creating tariff %s failed: %v", name, err) + instance = tariff.NewWrapper(conf.Type, conf.Other, err) + } + + return instance, nil +} + func configureTariff(name string, conf config.Typed, t *api.Tariff) error { if conf.Type == "" { return nil } - res, err := tariff.NewFromConfig(conf.Type, conf.Other) + res, err := tariffInstance(name, conf) if err != nil { return &DeviceError{name, err} } diff --git a/tariff/wrapper.go b/tariff/wrapper.go new file mode 100644 index 0000000000..8f97c889ae --- /dev/null +++ b/tariff/wrapper.go @@ -0,0 +1,43 @@ +package tariff + +import ( + "fmt" + + "github.com/evcc-io/evcc/api" +) + +// Wrapper wraps an api.Tariff to capture initialization errors +type Wrapper struct { + typ string + config map[string]interface{} + err error +} + +// NewWrapper creates an offline tariff wrapper +func NewWrapper(typ string, other map[string]interface{}, err error) api.Tariff { + v := &Wrapper{ + typ: typ, + config: other, + err: fmt.Errorf("tariff not available: %w", err), + } + + return v +} + +// // Error returns the initialization error +// func (v *Wrapper) Error() string { +// return v.err.Error() +// } + +// // Error returns the initialization error +// func (v *Wrapper) Config() (string, map[string]interface{}) { +// return v.typ, v.config +// } + +func (t *Wrapper) Rates() (api.Rates, error) { + return nil, t.err +} + +func (t *Wrapper) Type() api.TariffType { + return 0 +} diff --git a/vehicle/wrapper.go b/vehicle/wrapper.go index 6727185b26..2e2e24441b 100644 --- a/vehicle/wrapper.go +++ b/vehicle/wrapper.go @@ -17,7 +17,7 @@ type Wrapper struct { } // NewWrapper creates an offline Vehicle wrapper -func NewWrapper(name string, typ string, other map[string]interface{}, err error) api.Vehicle { +func NewWrapper(name, typ string, other map[string]interface{}, err error) api.Vehicle { var cc struct { embed `mapstructure:",squash"` Other map[string]interface{} `mapstructure:",remain"` @@ -44,18 +44,6 @@ func NewWrapper(name string, typ string, other map[string]interface{}, err error return v } -// Error returns the initialization error -func (v *Wrapper) Error() string { - return v.err.Error() -} - -// Error returns the initialization error -func (v *Wrapper) Config() (string, map[string]interface{}) { - return v.typ, v.config -} - -var _ api.Vehicle = (*Wrapper)(nil) - // SetTitle implements the api.TitleSetter interface func (v *Wrapper) SetTitle(title string) { v.Title_ = title From 4ae9f5262894cc741fe3861efc6c1d015f558227 Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 21 Sep 2024 12:05:53 +0200 Subject: [PATCH 2/3] wip --- tariff/wrapper.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tariff/wrapper.go b/tariff/wrapper.go index 8f97c889ae..47ebea901a 100644 --- a/tariff/wrapper.go +++ b/tariff/wrapper.go @@ -24,16 +24,6 @@ func NewWrapper(typ string, other map[string]interface{}, err error) api.Tariff return v } -// // Error returns the initialization error -// func (v *Wrapper) Error() string { -// return v.err.Error() -// } - -// // Error returns the initialization error -// func (v *Wrapper) Config() (string, map[string]interface{}) { -// return v.typ, v.config -// } - func (t *Wrapper) Rates() (api.Rates, error) { return nil, t.err } From 2c56872eb24c138a2e69aed02b31a9b70b619b10 Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 21 Sep 2024 12:07:22 +0200 Subject: [PATCH 3/3] wip --- tariff/wrapper.go | 7 +++++++ vehicle/wrapper.go | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/tariff/wrapper.go b/tariff/wrapper.go index 47ebea901a..70b430e51f 100644 --- a/tariff/wrapper.go +++ b/tariff/wrapper.go @@ -24,10 +24,17 @@ func NewWrapper(typ string, other map[string]interface{}, err error) api.Tariff return v } +// WrappedConfig indicates a device with wrapped configuration +func (v *Wrapper) WrappedConfig() (string, map[string]interface{}) { + return v.typ, v.config +} + +// Rates implements the api.Tariff interface func (t *Wrapper) Rates() (api.Rates, error) { return nil, t.err } +// Type implements the api.Tariff interface func (t *Wrapper) Type() api.TariffType { return 0 } diff --git a/vehicle/wrapper.go b/vehicle/wrapper.go index 2e2e24441b..09485a9ae5 100644 --- a/vehicle/wrapper.go +++ b/vehicle/wrapper.go @@ -44,6 +44,11 @@ func NewWrapper(name, typ string, other map[string]interface{}, err error) api.V return v } +// WrappedConfig indicates a device with wrapped configuration +func (v *Wrapper) WrappedConfig() (string, map[string]interface{}) { + return v.typ, v.config +} + // SetTitle implements the api.TitleSetter interface func (v *Wrapper) SetTitle(title string) { v.Title_ = title