Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tariffs: swallow startup errors #16258

Merged
merged 3 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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