Skip to content

Commit

Permalink
Tariffs: swallow startup errors (#16258)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig authored Sep 21, 2024
1 parent 3ca3955 commit 7b5edde
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
18 changes: 17 additions & 1 deletion cmd/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}
}
Expand Down
40 changes: 40 additions & 0 deletions tariff/wrapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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
}

// 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
}
13 changes: 3 additions & 10 deletions vehicle/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand All @@ -44,18 +44,11 @@ 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{}) {
// WrappedConfig indicates a device with wrapped configuration
func (v *Wrapper) WrappedConfig() (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
Expand Down

0 comments on commit 7b5edde

Please sign in to comment.