diff options
Diffstat (limited to 'errors')
-rwxr-xr-x | errors/debug_cap.go | 10 | ||||
-rwxr-xr-x | errors/debug_stack.go | 116 | ||||
-rwxr-xr-x | errors/debug_test.go | 74 | ||||
-rwxr-xr-x | errors/errors.go | 215 | ||||
-rwxr-xr-x | errors/marshal.go | 102 |
5 files changed, 0 insertions, 517 deletions
diff --git a/errors/debug_cap.go b/errors/debug_cap.go deleted file mode 100755 index 2c8a2f78..00000000 --- a/errors/debug_cap.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !debug - -package errors - -import "bytes" - -type stack struct{} - -func (e *Error) populateStack() {} -func (e *Error) printStack(*bytes.Buffer) {} diff --git a/errors/debug_stack.go b/errors/debug_stack.go deleted file mode 100755 index fa77ddc8..00000000 --- a/errors/debug_stack.go +++ /dev/null @@ -1,116 +0,0 @@ -// +build debug - -package errors - -import ( - "bytes" - "fmt" - "runtime" - "strings" -) - -type stack struct { - callers []uintptr - // TODO(adg): add time of creation -} - -func (e *Error) populateStack() { - e.callers = callers() - - e2, ok := e.Err.(*Error) - if !ok { - return - } - - i := 0 - - ok = false - for ; i < len(e.callers) && i < len(e2.callers); i++ { - // check for similar - if e.callers[len(e.callers)-1-i] != e2.callers[len(e2.callers)-1-i] { - break - } - ok = true - } - - if ok { //we have common PCs - e2Head := e2.callers[:len(e2.callers)-i] - eTail := e.callers - - e.callers = make([]uintptr, len(e2Head)+len(eTail)) - - copy(e.callers, e2Head) - copy(e.callers[len(e2Head):], eTail) - - e2.callers = nil - } -} - -// frame returns the nth frame, with the frame at top of stack being 0. -func frame(callers []uintptr, n int) runtime.Frame { - frames := runtime.CallersFrames(callers) - var f runtime.Frame - for i := len(callers) - 1; i >= n; i-- { - var ok bool - f, ok = frames.Next() - if !ok { - break - } - } - return f -} - -func (e *Error) printStack(b *bytes.Buffer) { - c := callers() - - var prev string - var diff bool - for i := 0; i < len(e.callers); i++ { - pc := e.callers[len(e.callers)-i-1] // get current PC - fn := runtime.FuncForPC(pc) // get function by pc - name := fn.Name() - - if !diff && i < len(c) { - ppc := c[len(c)-i-1] - pname := runtime.FuncForPC(ppc).Name() - if name == pname { - continue - } - diff = true - } - - if name == prev { - continue - } - - trim := 0 - for { - j := strings.IndexAny(name[trim:], "./") - if j < 0 { - break - } - if !strings.HasPrefix(prev, name[:j+trim]) { - break - } - trim += j + 1 // skip over the separator - } - - // Do the printing. - appendStrToBuf(b, Separator) - file, line := fn.FileLine(pc) - fmt.Fprintf(b, "%v:%d: ", file, line) - if trim > 0 { - b.WriteString("...") - } - b.WriteString(name[trim:]) - - prev = name - } -} - -func callers() []uintptr { - var stk [64]uintptr - const skip = 4 - n := runtime.Callers(skip, stk[:]) - return stk[:n] -} diff --git a/errors/debug_test.go b/errors/debug_test.go deleted file mode 100755 index bc866bc8..00000000 --- a/errors/debug_test.go +++ /dev/null @@ -1,74 +0,0 @@ -// +build debug - -package errors - -import ( - "fmt" - "regexp" - "strings" - "testing" -) - -var errorLines = strings.Split(strings.TrimSpace(` - .*/errors/debug_test.go:\d+: github.com/ValeryPiashchynski/errors.func1: - .*/errors/debug_test.go:\d+: ...T.func2: - .*/errors/debug_test.go:\d+: ...func3: - .*/errors/debug_test.go:\d+: ...func4: func2 invoke func3: Network error: - func4 operation: error in action -`), "\n") - -var errorLineREs = make([]*regexp.Regexp, len(errorLines)) - -func init() { - for i, s := range errorLines { - errorLineREs[i] = regexp.MustCompile(fmt.Sprintf("^%s", s)) - } -} - -func TestsDebug(t *testing.T) { - got := printErr(t, func1()) - lines := strings.Split(got, "\n") - for i, re := range errorLineREs { - if i >= len(lines) { - // Handled by line number check. - break - } - if !re.MatchString(lines[i]) { - t.Errorf("error does not match at line %v, got:\n\t%q\nwant:\n\t%q", i, lines[i], re) - } - } - if got, want := len(lines), len(errorLines); got != want { - t.Errorf("got %v lines of errors, want %v", got, want) - } -} - -type T struct{} - -func printErr(t *testing.T, err error) string { - return err.Error() -} - -func func1() error { - var t T - return t.func2() -} - -func (T) func2() error { - o := Op("func2 invoke func3") - return E(o, func3()) -} - -func func3() error { - return func4() -} - -func func4() error { - o := Op("func4 operation") - return E(o, Network, Str("error in action")) -} - -///Users/0xdev/Projects/repo/errors/debug_test.go:53: github.com/ValeryPiashchynski/errors.func1: -///Users/0xdev/Projects/repo/errors/debug_test.go:58: ...T.func2: -///Users/0xdev/Projects/repo/errors/debug_test.go:62: ...func3: -///Users/0xdev/Projects/repo/errors/debug_test.go:67: ...func4: func2 invoke func3: Network error: -//func4 operation: error in action diff --git a/errors/errors.go b/errors/errors.go deleted file mode 100755 index ec621b67..00000000 --- a/errors/errors.go +++ /dev/null @@ -1,215 +0,0 @@ -package errors - -import ( - "bytes" - "encoding" - "errors" - "fmt" - "log" - "runtime" -) - -type Error struct { - Op Op - Kind Kind - Err error - - // Stack information - stack -} - -func (e *Error) isZero() bool { - return e.Op == "" && e.Kind == 0 && e.Err == nil -} - -var ( - _ error = (*Error)(nil) - _ encoding.BinaryUnmarshaler = (*Error)(nil) - _ encoding.BinaryMarshaler = (*Error)(nil) -) - -// Op describes an operation -type Op string - -// separator -> new line plus tabulator to intend error if previuos not nil -var Separator = ":\n\t" - -type Kind uint8 - -// Kinds of errors. -const ( - Undefined Kind = iota // Undefined error. - ErrWatcherStopped - TimeOut -) - -func (k Kind) String() string { - switch k { - case Undefined: - return "UNDEF" - case ErrWatcherStopped: - return "Watcher stopped" - case TimeOut: - return "TimedOut" - } - return "unknown error kind" -} - -// E builds an error value from its arguments. -func E(args ...interface{}) error { - e := &Error{} - if len(args) == 0 { - msg := "errors.E called with 0 args" - _, file, line, ok := runtime.Caller(1) - if ok { - msg = fmt.Sprintf("%v - %v:%v", msg, file, line) - } - e.Err = errors.New(msg) - } - - for _, arg := range args { - switch arg := arg.(type) { - case Op: - e.Op = arg - case string: - e.Err = Str(arg) - case Kind: - e.Kind = arg - case *Error: - // Make a copy - eCopy := *arg - e.Err = &eCopy - case error: - e.Err = arg - // add map map[string]string - default: - _, file, line, _ := runtime.Caller(1) - log.Printf("errors.E: bad call from %s:%d: %v", file, line, args) - return Errorf("unknown type %T, value %v in error call", arg, arg) - } - } - - // Populate stack information - e.populateStack() - - prev, ok := e.Err.(*Error) - if !ok { - return e - } - - if prev.Kind == e.Kind { - prev.Kind = Undefined - } - - if e.Kind == Undefined { - e.Kind = prev.Kind - prev.Kind = Undefined - } - return e -} - -func (e *Error) Error() string { - b := new(bytes.Buffer) - e.printStack(b) - if e.Op != "" { - appendStrToBuf(b, ": ") - b.WriteString(string(e.Op)) - } - - if e.Kind != 0 { - appendStrToBuf(b, ": ") - b.WriteString(e.Kind.String()) - } - if e.Err != nil { - if prevErr, ok := e.Err.(*Error); ok { - if !prevErr.isZero() { - // indent - separator - appendStrToBuf(b, Separator) - b.WriteString(e.Err.Error()) - } - } else { - appendStrToBuf(b, ": ") - b.WriteString(e.Err.Error()) - } - } - if b.Len() == 0 { - return "no error" - } - return b.String() -} - -// errors.New -func Str(text string) error { - return &errorString{text} -} - -type errorString struct { - s string -} - -func (e *errorString) Error() string { - return e.s -} - -func Errorf(format string, args ...interface{}) error { - return &errorString{fmt.Sprintf(format, args...)} -} - -func Match(err1, err2 error) bool { - e1, ok := err1.(*Error) - if !ok { - return false - } - e2, ok := err2.(*Error) - if !ok { - return false - } - if e1.Op != "" && e2.Op != e1.Op { - return false - } - if e1.Kind != Undefined && e2.Kind != e1.Kind { - return false - } - if e1.Err != nil { - if _, ok := e1.Err.(*Error); ok { - return Match(e1.Err, e2.Err) - } - if e2.Err == nil || e2.Err.Error() != e1.Err.Error() { - return false - } - } - return true -} - -// Is reports whether err is an *Error of the given Kind -func Is(kind Kind, err error) bool { - e, ok := err.(*Error) - if !ok { - return false - } - if e.Kind != Undefined { - return e.Kind == kind - } - if e.Err != nil { - return Is(kind, e.Err) - } - return false -} - -// Do smt with no care about result (and panics) -func SafelyDo(work func()) { - defer func() { - if err := recover(); err != nil { - log.Printf("work failed: %s", err) - } - }() - - work() -} - -func appendStrToBuf(b *bytes.Buffer, str string) { - if b.Len() == 0 { - return - } - b.WriteString(str) -} diff --git a/errors/marshal.go b/errors/marshal.go deleted file mode 100755 index 7c8a63ef..00000000 --- a/errors/marshal.go +++ /dev/null @@ -1,102 +0,0 @@ -package errors - -import ( - "encoding/binary" - "log" -) - -func (e *Error) MarshalAppend(b []byte) []byte { - if e == nil { - return b - } - - b = appendString(b, string(e.Op)) - - var tmp [16]byte - N := binary.PutVarint(tmp[:], int64(e.Kind)) - b = append(b, tmp[:N]...) - b = MarshalErrorAppend(e.Err, b) - return b -} - -func (e *Error) MarshalBinary() ([]byte, error) { - return e.MarshalAppend(nil), nil -} - -func MarshalErrorAppend(err error, b []byte) []byte { - if err == nil { - return b - } - if e, ok := err.(*Error); ok { - b = append(b, 'E') - return e.MarshalAppend(b) - } - // Ordinary error. - b = append(b, 'e') - b = appendString(b, err.Error()) - return b -} - -func MarshalError(err error) []byte { - return MarshalErrorAppend(err, nil) -} - -func (e *Error) UnmarshalBinary(b []byte) error { - if len(b) == 0 { - return nil - } - data, b := getBytes(b) - if data != nil { - e.Op = Op(data) - } - k, N := binary.Varint(b) - e.Kind = Kind(k) - b = b[N:] - e.Err = UnmarshalError(b) - return nil -} - -func UnmarshalError(b []byte) error { - if len(b) == 0 { - return nil - } - code := b[0] - b = b[1:] - switch code { - case 'e': - var data []byte - data, b = getBytes(b) - if len(b) != 0 { - log.Printf("Unmarshal error: trailing bytes") - } - return Str(string(data)) - case 'E': - var err Error - err.UnmarshalBinary(b) - return &err - default: - log.Printf("Unmarshal error: corrupt data %q", b) - return Str(string(b)) - } -} - -func appendString(b []byte, str string) []byte { - var tmp [16]byte - N := binary.PutUvarint(tmp[:], uint64(len(str))) - b = append(b, tmp[:N]...) - b = append(b, str...) - return b -} - -func getBytes(b []byte) (data, remaining []byte) { - u, N := binary.Uvarint(b) - if len(b) < N+int(u) { - log.Printf("Unmarshal error: bad encoding") - return nil, nil - } - if N == 0 { - log.Printf("Unmarshal error: bad encoding") - return nil, b - } - return b[N : N+int(u)], b[N+int(u):] -} |