2016-08-18 20:20:33 +00:00
|
|
|
// Package errors provides common error handling tools
|
2016-05-18 10:43:42 +00:00
|
|
|
// NOTE: Subject to change, do not rely on this package from outside git-lfs source
|
2016-08-18 20:20:33 +00:00
|
|
|
package errors
|
2014-08-07 22:04:04 +00:00
|
|
|
|
2015-08-21 16:15:29 +00:00
|
|
|
// The LFS error system provides a simple wrapper around Go errors and the
|
|
|
|
// ability to inspect errors. It is strongly influenced by Dave Cheney's post
|
|
|
|
// at http://dave.cheney.net/2014/12/24/inspecting-errors.
|
|
|
|
//
|
|
|
|
// When passing errors out of lfs package functions, the return type should
|
|
|
|
// always be `error`. The wrappedError details are not exported. If an error is
|
|
|
|
// the kind of error a caller should need to investigate, an IsXError()
|
|
|
|
// function is provided that tells the caller if the error is of that type.
|
|
|
|
// There should only be a handfull of cases where a simple `error` is
|
|
|
|
// insufficient.
|
|
|
|
//
|
|
|
|
// The error behaviors can be nested when created. For example, the not
|
|
|
|
// implemented error can also be marked as a fatal error:
|
|
|
|
//
|
|
|
|
// func LfsFunction() error {
|
|
|
|
// err := functionCall()
|
|
|
|
// if err != nil {
|
|
|
|
// return newFatalError(newNotImplementedError(err))
|
|
|
|
// }
|
|
|
|
// return nil
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// Then in the caller:
|
|
|
|
//
|
|
|
|
// err := lfs.LfsFunction()
|
|
|
|
// if lfs.IsNotImplementedError(err) {
|
|
|
|
// log.Print("feature not implemented")
|
|
|
|
// }
|
|
|
|
// if lfs.IsFatalError(err) {
|
|
|
|
// os.Exit(1)
|
|
|
|
// }
|
2015-08-21 19:33:00 +00:00
|
|
|
//
|
|
|
|
// Wrapped errors contain a context, which is a map[string]string. These
|
|
|
|
// contexts can be accessed through the Error*Context functions. Calling these
|
|
|
|
// functions on a regular Go error will have no effect.
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
//
|
|
|
|
// err := lfs.SomeFunction()
|
2016-08-18 20:20:33 +00:00
|
|
|
// errors.ErrorSetContext(err, "foo", "bar")
|
|
|
|
// errors.ErrorGetContext(err, "foo") // => "bar"
|
|
|
|
// errors.ErrorDelContext(err, "foo")
|
2015-08-21 19:33:00 +00:00
|
|
|
//
|
|
|
|
// Wrapped errors also contain the stack from the point at which they are
|
2016-08-18 22:02:58 +00:00
|
|
|
// called. Use the '%+v' printf verb to display. See the github.com/pkg/errors
|
|
|
|
// docs for more info: https://godoc.org/github.com/pkg/errors
|
2015-08-21 16:15:29 +00:00
|
|
|
|
2014-08-07 22:04:04 +00:00
|
|
|
import (
|
2015-08-27 16:04:52 +00:00
|
|
|
"fmt"
|
2016-08-17 22:54:59 +00:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2014-08-07 22:04:04 +00:00
|
|
|
)
|
|
|
|
|
2016-08-18 20:20:33 +00:00
|
|
|
// New returns an error with the supplied message. New also records the stack
|
|
|
|
// trace at thepoint it was called.
|
|
|
|
func New(message string) error {
|
|
|
|
return errors.New(message)
|
|
|
|
}
|
|
|
|
|
2016-08-18 21:02:21 +00:00
|
|
|
// Errorf formats according to a format specifier and returns the string
|
|
|
|
// as a value that satisfies error.
|
|
|
|
// Errorf also records the stack trace at the point it was called.
|
|
|
|
func Errorf(format string, args ...interface{}) error {
|
|
|
|
return errors.Errorf(format, args...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wrap wraps an error with an additional message.
|
|
|
|
func Wrap(err error, msg string) error {
|
|
|
|
return newWrappedError(err, msg)
|
2016-08-18 20:20:33 +00:00
|
|
|
}
|
|
|
|
|
2016-08-18 20:35:11 +00:00
|
|
|
// Wrapf wraps an error with an additional formatted message.
|
|
|
|
func Wrapf(err error, format string, args ...interface{}) error {
|
2016-08-18 20:20:33 +00:00
|
|
|
if err == nil {
|
|
|
|
err = errors.New("")
|
|
|
|
}
|
|
|
|
|
2016-08-18 20:35:11 +00:00
|
|
|
message := fmt.Sprintf(format, args...)
|
2016-08-18 20:20:33 +00:00
|
|
|
|
|
|
|
return newWrappedError(err, message)
|
|
|
|
}
|
2016-08-19 18:30:53 +00:00
|
|
|
|
|
|
|
func StackTrace(err error) []string {
|
|
|
|
type stacktrace interface {
|
|
|
|
StackTrace() errors.StackTrace
|
|
|
|
}
|
|
|
|
|
|
|
|
if err, ok := err.(stacktrace); ok {
|
|
|
|
frames := err.StackTrace()
|
|
|
|
lines := make([]string, len(frames))
|
|
|
|
for i, f := range frames {
|
|
|
|
lines[i] = fmt.Sprintf("%+v", f)
|
|
|
|
}
|
|
|
|
return lines
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|