Skip to content

Commit

Permalink
Always make fatal errors json-serializable (#14396)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig committed Jun 16, 2024
1 parent a8f95ef commit 4d6109d
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
21 changes: 21 additions & 0 deletions cmd/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,27 @@ const (
ClassSponsorship
)

// FatalError is an error that can be marshaled
type FatalError struct {
err error
}

func (e *FatalError) Error() string {
return e.err.Error()
}

func (e FatalError) MarshalJSON() ([]byte, error) {
if je, ok := e.err.(json.Marshaler); ok {
return je.MarshalJSON()
}

return json.Marshal(struct {
Error string `json:"error"`
}{
Error: e.err.Error(),
})
}

// DeviceError indicates the specific device that failed
type DeviceError struct {
Name string
Expand Down
30 changes: 16 additions & 14 deletions cmd/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,25 @@ func shutdownDoneC() <-chan struct{} {
return doneC
}

func wrapError(err error) error {
if err != nil {
var opErr *net.OpError
var pathErr *os.PathError
func wrapFatalError(err error) error {
if err == nil {
return nil
}

var opErr *net.OpError
var pathErr *os.PathError

switch {
case errors.As(err, &opErr):
if opErr.Op == "listen" && strings.Contains(opErr.Error(), "address already in use") {
err = fmt.Errorf("could not open port- check that evcc is not already running (%w)", err)
}
switch {
case errors.As(err, &opErr):
if opErr.Op == "listen" && strings.Contains(opErr.Error(), "address already in use") {
err = fmt.Errorf("could not open port- check that evcc is not already running (%w)", err)
}

case errors.As(err, &pathErr):
if pathErr.Op == "remove" && strings.Contains(pathErr.Error(), "operation not permitted") {
err = fmt.Errorf("could not remove file- check that evcc is not already running (%w)", err)
}
case errors.As(err, &pathErr):
if pathErr.Op == "remove" && strings.Contains(pathErr.Error(), "operation not permitted") {
err = fmt.Errorf("could not remove file- check that evcc is not already running (%w)", err)
}
}

return err
return &FatalError{err}
}
4 changes: 2 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ func runRoot(cmd *cobra.Command, args []string) {

if err != nil {
// improve error message
err = wrapError(err)
err = wrapFatalError(err)
valueChan <- util.Param{Key: keys.Fatal, Val: err}

// TODO stop reboot loop if user updates config (or show countdown in UI)
Expand All @@ -307,5 +307,5 @@ func runRoot(cmd *cobra.Command, args []string) {
// uds health check listener
go server.HealthListener(site)

log.FATAL.Println(wrapError(httpd.ListenAndServe()))
log.FATAL.Println(wrapFatalError(httpd.ListenAndServe()))
}

0 comments on commit 4d6109d

Please sign in to comment.