1package errors 2 3import ( 4 "fmt" 5 "log" 6 "runtime" 7 "strings" 8) 9 10var SkipLogging map[string]bool 11 12func init() { 13 SkipLogging = make(map[string]bool, 10) 14} 15 16type Error struct { 17 Errs []error 18 Stack []byte 19} 20 21func Errorf(format string, args ...interface{}) error { 22 buf := make([]byte, 50000) 23 n := runtime.Stack(buf, true) 24 trace := make([]byte, n) 25 copy(trace, buf) 26 return &Error{ 27 Errs: []error{fmt.Errorf(format, args...)}, 28 Stack: trace, 29 } 30} 31 32func Logf(level, format string, args ...interface{}) { 33 if SkipLogging[level] { 34 return 35 } 36 pc, _, line, ok := runtime.Caller(1) 37 if !ok { 38 log.Printf(format, args) 39 return 40 } 41 fn := runtime.FuncForPC(pc) 42 msg := fmt.Sprintf(format, args...) 43 log.Printf("%v (%v:%v): %v", level, fn.Name(), line, msg) 44} 45 46func (e *Error) Chain(err error) error { 47 e.Errs = append(e.Errs, err) 48 return e 49} 50 51func (e *Error) Error() string { 52 if e == nil { 53 return "Error <nil>" 54 } else if len(e.Errs) == 0 { 55 return fmt.Sprintf("%v\n%s", e.Errs, string(e.Stack)) 56 } else if len(e.Errs) == 1 { 57 return fmt.Sprintf("%v\n%s", e.Errs[0], string(e.Stack)) 58 } else { 59 errs := make([]string, 0, len(e.Errs)) 60 for _, err := range e.Errs { 61 errs = append(errs, err.Error()) 62 } 63 return fmt.Sprintf("{%v}\n%s", strings.Join(errs, ", "), string(e.Stack)) 64 } 65} 66 67func (e *Error) String() string { 68 return e.Error() 69} 70 71type ErrorFmter func(a ...interface{}) error 72 73func NotFound(a ...interface{}) error { 74 // return fmt.Errorf("Key '%v' was not found.", a...) 75 return Errorf("Key was not found.") 76} 77 78func NotFoundInBucket(a ...interface{}) error { 79 return Errorf("Key, '%v', was not in bucket when expected.", a...) 80} 81 82func InvalidKey(a ...interface{}) error { 83 return Errorf("Key, '%v', is invalid, %s", a...) 84} 85 86func TSTError(a ...interface{}) error { 87 return Errorf("Internal TST error - "+a[0].(string), a[1:]...) 88} 89 90func NegativeSize(a ...interface{}) error { 91 return Errorf("Negative size") 92} 93 94func BpTreeError(a ...interface{}) error { 95 return Errorf("Internal B+ Tree error - "+a[0].(string), a[1:]...) 96} 97 98var Errors map[string]ErrorFmter = map[string]ErrorFmter{ 99 "not-found": NotFound, 100 "not-found-in-bucket": NotFoundInBucket, 101 "invalid-key": InvalidKey, 102 "tst-error": TSTError, 103 "negative-size": NegativeSize, 104 "bptree-error": BpTreeError, 105} 106