summaryrefslogtreecommitdiff
path: root/vendor/github.com/dropbox/godropbox/errors/errors.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/dropbox/godropbox/errors/errors.go')
-rw-r--r--vendor/github.com/dropbox/godropbox/errors/errors.go260
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
-}