github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/errorhandling/errorhandling.go (about) 1 package errorhandling 2 3 import ( 4 "os" 5 "strings" 6 7 "github.com/hashicorp/go-multierror" 8 "github.com/pkg/errors" 9 "github.com/sirupsen/logrus" 10 ) 11 12 // JoinErrors converts the error slice into a single human-readable error. 13 func JoinErrors(errs []error) error { 14 if len(errs) == 0 { 15 return nil 16 } 17 18 // If there's just one error, return it. This prevents the "%d errors 19 // occurred:" header plus list from the multierror package. 20 if len(errs) == 1 { 21 return errs[0] 22 } 23 24 // `multierror` appends new lines which we need to remove to prevent 25 // blank lines when printing the error. 26 var multiE *multierror.Error 27 multiE = multierror.Append(multiE, errs...) 28 29 finalErr := multiE.ErrorOrNil() 30 if finalErr == nil { 31 return nil 32 } 33 return errors.New(strings.TrimSpace(finalErr.Error())) 34 } 35 36 // ErrorsToString converts the slice of errors into a slice of corresponding 37 // error messages. 38 func ErrorsToStrings(errs []error) []string { 39 if len(errs) == 0 { 40 return nil 41 } 42 strErrs := make([]string, len(errs)) 43 for i := range errs { 44 strErrs[i] = errs[i].Error() 45 } 46 return strErrs 47 } 48 49 // StringsToErrors converts a slice of error messages into a slice of 50 // corresponding errors. 51 func StringsToErrors(strErrs []string) []error { 52 if len(strErrs) == 0 { 53 return nil 54 } 55 errs := make([]error, len(strErrs)) 56 for i := range strErrs { 57 errs[i] = errors.New(strErrs[i]) 58 } 59 return errs 60 } 61 62 // SyncQuiet syncs a file and logs any error. Should only be used within 63 // a defer. 64 func SyncQuiet(f *os.File) { 65 if err := f.Sync(); err != nil { 66 logrus.Errorf("Unable to sync file %s: %q", f.Name(), err) 67 } 68 } 69 70 // CloseQuiet closes a file and logs any error. Should only be used within 71 // a defer. 72 func CloseQuiet(f *os.File) { 73 if err := f.Close(); err != nil { 74 logrus.Errorf("Unable to close file %s: %q", f.Name(), err) 75 } 76 } 77 78 // Contains checks if err's message contains sub's message. Contains should be 79 // used iff either err or sub has lost type information (e.g., due to 80 // marshaling). For typed errors, please use `errors.Contains(...)` or `Is()` 81 // in recent version of Go. 82 func Contains(err error, sub error) bool { 83 return strings.Contains(err.Error(), sub.Error()) 84 } 85 86 // PodConflictErrorModel is used in remote connections with podman 87 type PodConflictErrorModel struct { 88 Errs []string 89 Id string // nolint 90 } 91 92 // ErrorModel is used in remote connections with podman 93 type ErrorModel struct { 94 // API root cause formatted for automated parsing 95 // example: API root cause 96 Because string `json:"cause"` 97 // human error message, formatted for a human to read 98 // example: human error message 99 Message string `json:"message"` 100 // HTTP response code 101 // min: 400 102 ResponseCode int `json:"response"` 103 } 104 105 func (e ErrorModel) Error() string { 106 return e.Message 107 } 108 109 func (e ErrorModel) Cause() error { 110 return errors.New(e.Because) 111 } 112 113 func (e ErrorModel) Code() int { 114 return e.ResponseCode 115 } 116 117 func (e PodConflictErrorModel) Error() string { 118 return strings.Join(e.Errs, ",") 119 } 120 121 func (e PodConflictErrorModel) Code() int { 122 return 409 123 }