Skip to content

Commit

Permalink
pkg/podman: Add error parsing method
Browse files Browse the repository at this point in the history
This new helper function parses the output of Podman in stderr into
a dedicated structure with defined methods for working with the error.

The most significant part is the method Is() that wraps around
errors.Is() and if that fails to find a match resorts to string
matching. This is needed because there are no defined errors to catch
errors coming from Podman.

The structure is only meant to be used internally.
  • Loading branch information
HarryMichal committed Jun 7, 2021
1 parent 1df3659 commit afd427d
Showing 1 changed file with 64 additions and 0 deletions.
64 changes: 64 additions & 0 deletions src/pkg/podman/podman.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ package podman
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"sort"
"strings"

"github.com/HarryMichal/go-version"
"github.com/containers/toolbox/pkg/shell"
Expand Down Expand Up @@ -332,3 +335,64 @@ func SystemMigrate(ociRuntimeRequired string) error {

return nil
}

type internalError struct {
Err error
}

func (e *internalError) Error() string {
if e.Err == nil {
return ""
}
return e.Err.Error()
}

func (e *internalError) Wrap(format string, a ...interface{}) {
errMsg := fmt.Sprintf(format, a...)
if e.Err == nil {
e.Err = errors.New(errMsg)
} else {
e.Err = fmt.Errorf("%v: %w", errMsg, e.Err)
}
}

// Is wraps around errors.Is() and add support for string comparison of errors
func (e internalError) Is(err error) bool {
if errors.Is(e.Err, err) {
return true
}

errMsgParts := strings.Split(e.Err.Error(), ": ")
for _, part := range errMsgParts {
if part == err.Error() {
return true
}
}

return false
}

// parseErrorMsg serves for converting error output of Podman into an error
// that can be further used in Go.
//
// The returned error can be examined using methods Unwrap, Is & As.
func parseErrorMsg(stderr *bytes.Buffer) internalError {
var err internalError
var errMsg string
var errMsgParts []string

errMsg = stderr.String()
errMsg = strings.TrimSpace(errMsg)
// Podman error messages are usually prepended with the "Error: " string
errMsg = strings.TrimPrefix(errMsg, "Error: ")
// Wrapped error messages are usually separated by a colon followed by
// a single space character
errMsgParts = strings.Split(errMsg, ": ")

// Wrapping happens from the first to the last error
for i := len(errMsgParts) - 1; i >= 0; i-- {
err.Wrap(errMsgParts[i])
}

return err
}

0 comments on commit afd427d

Please sign in to comment.