github.com/pavlo67/common@v0.5.3/common/errors/errors.go (about)

     1  package errors
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  	"strings"
     8  
     9  	"github.com/pavlo67/common/common"
    10  )
    11  
    12  type Key = common.ErrorKey
    13  
    14  type Error interface {
    15  	error
    16  	Cause() error
    17  	Key() Key
    18  	Data() common.Map
    19  	Append(interface{}) Error
    20  }
    21  
    22  func CommonError(any ...interface{}) Error {
    23  	var err *commonError
    24  	for _, anything := range any {
    25  		err = err.append(anything)
    26  	}
    27  
    28  	if reflect.ValueOf(err).IsNil() {
    29  		return nil
    30  	}
    31  
    32  	return err
    33  }
    34  
    35  func AddErrors(err, errToAdd error) error {
    36  	if err == nil {
    37  		return errToAdd
    38  	} else if v := reflect.ValueOf(err); v.Kind() == reflect.Interface && v.IsNil() {
    39  		return errToAdd
    40  	} else if e, _ := err.(Error); e != nil {
    41  		return e.Append(errToAdd)
    42  	}
    43  
    44  	return CommonError(err, errToAdd)
    45  }
    46  
    47  //func CommonError(key Key, data common.Map) Error {
    48  //	return &commonError{
    49  //		errs: nil,
    50  //		key:  key,
    51  //		data: data,
    52  //	}
    53  //}
    54  
    55  func Keyed(err error) Key {
    56  	if err == nil {
    57  		return ""
    58  	}
    59  
    60  	if errs, _ := err.(Error); errs != nil {
    61  		return errs.Key()
    62  	}
    63  	return ""
    64  }
    65  
    66  func Cause(err error) error {
    67  	if err == nil {
    68  		return nil
    69  	}
    70  
    71  	if errs, _ := err.(Error); errs != nil {
    72  		return errs.Cause()
    73  	}
    74  	return nil
    75  }
    76  
    77  func Data(err error) common.Map {
    78  	if err == nil {
    79  		return nil
    80  	}
    81  
    82  	if errs, _ := err.(Error); errs != nil {
    83  		return errs.Data()
    84  	}
    85  	return nil
    86  }
    87  
    88  // commonError -------------------------------------------------------------------------------------------------------
    89  
    90  var _ Error = &commonError{}
    91  
    92  type commonError struct {
    93  	errs multipleErrors
    94  	key  Key
    95  	data common.Map
    96  }
    97  
    98  func (ce *commonError) Cause() error {
    99  	if ce != nil {
   100  		if len(ce.errs) > 0 {
   101  			return ce.errs[0]
   102  		} else if ce.key != "" {
   103  			// ???
   104  			New(string(ce.key))
   105  		}
   106  	}
   107  
   108  	return nil
   109  }
   110  
   111  func (ce *commonError) Error() string {
   112  	if ce == nil {
   113  		return ""
   114  	}
   115  	errStr := strings.TrimSpace(string(ce.key))
   116  	if errStr == "" {
   117  		// errStr = "<no key> "
   118  	}
   119  
   120  	if len(ce.data) > 0 {
   121  		errStr += fmt.Sprintf(" (%v) ", ce.data)
   122  	}
   123  
   124  	return errStr + ce.errs.String()
   125  }
   126  
   127  func (ce *commonError) Key() Key {
   128  	if ce == nil {
   129  		return ""
   130  	}
   131  
   132  	return ce.key
   133  }
   134  
   135  func (ce *commonError) Data() common.Map {
   136  	if ce == nil {
   137  		return nil
   138  	}
   139  
   140  	return ce.data
   141  }
   142  
   143  func (ce *commonError) append(anything interface{}) *commonError {
   144  	if anything == nil {
   145  		return ce
   146  	}
   147  
   148  	switch v := anything.(type) {
   149  	case Key:
   150  		if ce == nil {
   151  			return &commonError{key: v}
   152  		} else if ce.key == "" {
   153  			ce.key = v
   154  			return ce
   155  		} else {
   156  			anything = commonError{key: v}
   157  		}
   158  	case common.Map:
   159  		if ce == nil {
   160  			return &commonError{data: v}
   161  		} else if len(ce.data) < 1 {
   162  			ce.data = v
   163  			return ce
   164  		} else {
   165  			anything = commonError{data: v}
   166  		}
   167  	case string:
   168  		anything = errors.New(v)
   169  	}
   170  
   171  	if ce == nil {
   172  		switch v := anything.(type) {
   173  		case commonError:
   174  			v1 := v //  to prevent recursion in the case: ke1 := CommonError(...); ke2 := CommonError(ke1, ke1)
   175  			return &v1
   176  		case *commonError:
   177  			v1 := *v // to prevent recursion in the case: ke1 := CommonError(...); ke2 := CommonError(ke1, ke1)
   178  			return &v1
   179  		case Error:
   180  			return &commonError{
   181  				errs: multipleErrors{errors.New(v.Error())},
   182  				key:  v.Key(),
   183  				data: v.Data(),
   184  			}
   185  		case error:
   186  			return &commonError{errs: multipleErrors{v}}
   187  		case string:
   188  			return &commonError{errs: multipleErrors{errors.New(v)}}
   189  		}
   190  		ce = &commonError{}
   191  	}
   192  
   193  	var err error
   194  	switch v := anything.(type) {
   195  	case commonError:
   196  		err = &v
   197  	case *commonError:
   198  		err = v
   199  	case Error:
   200  		err = v
   201  	case error:
   202  		err = v
   203  	case string:
   204  		err = errors.New(v)
   205  	default:
   206  	}
   207  
   208  	ce.errs = append(ce.errs, err)
   209  	return ce
   210  }
   211  
   212  func (ce *commonError) Append(anything interface{}) Error {
   213  	return ce.append(anything)
   214  
   215  }