diff options
author | Ruben Pollan <meskio@sindominio.net> | 2021-01-25 17:56:26 +0100 |
---|---|---|
committer | kali kaneko (leap communications) <kali@leap.se> | 2021-02-25 21:34:10 +0100 |
commit | 0b50eca211bda4d0c1cb28973126f0269288bb71 (patch) | |
tree | 09d374ade952a2366292ec6d8ab8b174b0581a2c /vendor/github.com/dropbox/godropbox/errors/errors.go | |
parent | ec03343a76291f10fd2216ef74addff98b9701f9 (diff) |
Use go modules & and devendorize
spring clean for menshen!
Diffstat (limited to 'vendor/github.com/dropbox/godropbox/errors/errors.go')
-rw-r--r-- | vendor/github.com/dropbox/godropbox/errors/errors.go | 260 |
1 files changed, 0 insertions, 260 deletions
diff --git a/vendor/github.com/dropbox/godropbox/errors/errors.go b/vendor/github.com/dropbox/godropbox/errors/errors.go deleted file mode 100644 index 8090784..0000000 --- a/vendor/github.com/dropbox/godropbox/errors/errors.go +++ /dev/null @@ -1,260 +0,0 @@ -// This module implements functions which manipulate errors and provide stack -// trace information. -// -// NOTE: This package intentionally mirrors the standard "errors" module. -// All dropbox code should use this. -package errors - -import ( - "bytes" - "fmt" - "reflect" - "runtime" - "sync" -) - -// This interface exposes additional information about the error. -type DropboxError interface { - // This returns the error message without the stack trace. - GetMessage() string - - // This returns the wrapped error. This returns nil if this does not wrap - // another error. - GetInner() error - - // Implements the built-in error interface. - Error() string - - // Returns stack addresses as a string that can be supplied to - // a helper tool to get the actual stack trace. This function doesn't result - // in resolving full stack frames thus is a lot more efficient. - StackAddrs() string - - // Returns stack frames. - StackFrames() []StackFrame - - // Returns string representation of stack frames. - // Stack frame formatting looks generally something like this: - // dropbox/rpc.(*clientV4).Do - // /srv/server/go/src/dropbox/rpc/client.go:87 +0xbf9 - // dropbox/exclog.Report - // /srv/server/go/src/dropbox/exclog/client.go:129 +0x9e5 - // main.main - // /home/cdo/tmp/report_exception.go:13 +0x84 - // It is discouraged to parse stack frames using string parsing since it can change at any time. - // Use StackFrames() function instead to get actual stack frame metadata. - GetStack() string -} - -// Represents a single stack frame. -type StackFrame struct { - PC uintptr - Func *runtime.Func - FuncName string - File string - LineNumber int -} - -// Standard struct for general types of errors. -// -// For an example of custom error type, look at databaseError/newDatabaseError -// in errors_test.go. -type baseError struct { - msg string - inner error - - stack []uintptr - framesOnce sync.Once - stackFrames []StackFrame -} - -// This returns the error string without stack trace information. -func GetMessage(err interface{}) string { - switch e := err.(type) { - case DropboxError: - return extractFullErrorMessage(e, false) - case runtime.Error: - return runtime.Error(e).Error() - case error: - return e.Error() - default: - return "Passed a non-error to GetMessage" - } -} - -// This returns a string with all available error information, including inner -// errors that are wrapped by this errors. -func (e *baseError) Error() string { - return extractFullErrorMessage(e, true) -} - -// Implements DropboxError interface. -func (e *baseError) GetMessage() string { - return e.msg -} - -// Implements DropboxError interface. -func (e *baseError) GetInner() error { - return e.inner -} - -// Implements DropboxError interface. -func (e *baseError) StackAddrs() string { - buf := bytes.NewBuffer(make([]byte, 0, len(e.stack)*8)) - for _, pc := range e.stack { - fmt.Fprintf(buf, "0x%x ", pc) - } - bufBytes := buf.Bytes() - return string(bufBytes[:len(bufBytes)-1]) -} - -// Implements DropboxError interface. -func (e *baseError) StackFrames() []StackFrame { - e.framesOnce.Do(func() { - e.stackFrames = make([]StackFrame, len(e.stack)) - for i, pc := range e.stack { - frame := &e.stackFrames[i] - frame.PC = pc - frame.Func = runtime.FuncForPC(pc) - if frame.Func != nil { - frame.FuncName = frame.Func.Name() - frame.File, frame.LineNumber = frame.Func.FileLine(frame.PC - 1) - } - } - }) - return e.stackFrames -} - -// Implements DropboxError interface. -func (e *baseError) GetStack() string { - stackFrames := e.StackFrames() - buf := bytes.NewBuffer(make([]byte, 0, 256)) - for _, frame := range stackFrames { - _, _ = buf.WriteString(frame.FuncName) - _, _ = buf.WriteString("\n") - fmt.Fprintf(buf, "\t%s:%d +0x%x\n", - frame.File, frame.LineNumber, frame.PC) - } - return buf.String() -} - -// This returns a new baseError initialized with the given message and -// the current stack trace. -func New(msg string) DropboxError { - return new(nil, msg) -} - -// Same as New, but with fmt.Printf-style parameters. -func Newf(format string, args ...interface{}) DropboxError { - return new(nil, fmt.Sprintf(format, args...)) -} - -// Wraps another error in a new baseError. -func Wrap(err error, msg string) DropboxError { - return new(err, msg) -} - -// Same as Wrap, but with fmt.Printf-style parameters. -func Wrapf(err error, format string, args ...interface{}) DropboxError { - return new(err, fmt.Sprintf(format, args...)) -} - -// Internal helper function to create new baseError objects, -// note that if there is more than one level of redirection to call this function, -// stack frame information will include that level too. -func new(err error, msg string) *baseError { - stack := make([]uintptr, 200) - stackLength := runtime.Callers(3, stack) - return &baseError{ - msg: msg, - stack: stack[:stackLength], - inner: err, - } -} - -// Constructs full error message for a given DropboxError by traversing -// all of its inner errors. If includeStack is True it will also include -// stack trace from deepest DropboxError in the chain. -func extractFullErrorMessage(e DropboxError, includeStack bool) string { - var ok bool - var lastDbxErr DropboxError - errMsg := bytes.NewBuffer(make([]byte, 0, 1024)) - - dbxErr := e - for { - lastDbxErr = dbxErr - errMsg.WriteString(dbxErr.GetMessage()) - - innerErr := dbxErr.GetInner() - if innerErr == nil { - break - } - dbxErr, ok = innerErr.(DropboxError) - if !ok { - // We have reached the end and traveresed all inner errors. - // Add last message and exit loop. - errMsg.WriteString(innerErr.Error()) - break - } - errMsg.WriteString("\n") - } - if includeStack { - errMsg.WriteString("\nORIGINAL STACK TRACE:\n") - errMsg.WriteString(lastDbxErr.GetStack()) - } - return errMsg.String() -} - -// Return a wrapped error or nil if there is none. -func unwrapError(ierr error) (nerr error) { - // Internal errors have a well defined bit of context. - if dbxErr, ok := ierr.(DropboxError); ok { - return dbxErr.GetInner() - } - - // At this point, if anything goes wrong, just return nil. - defer func() { - if x := recover(); x != nil { - nerr = nil - } - }() - - // Go system errors have a convention but paradoxically no - // interface. All of these panic on error. - errV := reflect.ValueOf(ierr).Elem() - errV = errV.FieldByName("Err") - return errV.Interface().(error) -} - -// Keep peeling away layers or context until a primitive error is revealed. -func RootError(ierr error) (nerr error) { - nerr = ierr - for i := 0; i < 20; i++ { - terr := unwrapError(nerr) - if terr == nil { - return nerr - } - nerr = terr - } - return fmt.Errorf("too many iterations: %T", nerr) -} - -// Perform a deep check, unwrapping errors as much as possilbe and -// comparing the string version of the error. -func IsError(err, errConst error) bool { - if err == errConst { - return true - } - // Must rely on string equivalence, otherwise a value is not equal - // to its pointer value. - rootErrStr := "" - rootErr := RootError(err) - if rootErr != nil { - rootErrStr = rootErr.Error() - } - errConstStr := "" - if errConst != nil { - errConstStr = errConst.Error() - } - return rootErrStr == errConstStr -} |