Merge pull request #1466 from github/errutil-to-errors

Errutil to errors
This commit is contained in:
risk danger olson 2016-08-19 12:13:52 -08:00 committed by GitHub
commit ddfaae3c3a
32 changed files with 343 additions and 387 deletions

@ -9,7 +9,7 @@ import (
"strconv"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/git"
"github.com/github/git-lfs/httputil"
"github.com/github/git-lfs/tools"
@ -27,7 +27,7 @@ func BatchOrLegacy(cfg *config.Configuration, objects []*ObjectResource, operati
}
objs, adapterName, err := Batch(cfg, objects, operation, transferAdapters)
if err != nil {
if errutil.IsNotImplementedError(err) {
if errors.IsNotImplementedError(err) {
git.Config.SetLocal("", "lfs.batch", "false")
objs, err := Legacy(cfg, objects, operation)
return objs, "", err
@ -63,12 +63,12 @@ func Batch(cfg *config.Configuration, objects []*ObjectResource, operation strin
o := &batchRequest{Operation: operation, Objects: objects, TransferAdapterNames: transferAdapters}
by, err := json.Marshal(o)
if err != nil {
return nil, "", errutil.Error(err)
return nil, "", errors.Wrap(err, "batch request")
}
req, err := NewBatchRequest(cfg, operation)
if err != nil {
return nil, "", errutil.Error(err)
return nil, "", errors.Wrap(err, "batch request")
}
req.Header.Set("Content-Type", MediaType)
@ -81,33 +81,31 @@ func Batch(cfg *config.Configuration, objects []*ObjectResource, operation strin
res, bresp, err := DoBatchRequest(cfg, req)
if err != nil {
if res == nil {
return nil, "", errutil.NewRetriableError(err)
return nil, "", errors.NewRetriableError(err)
}
if res.StatusCode == 0 {
return nil, "", errutil.NewRetriableError(err)
return nil, "", errors.NewRetriableError(err)
}
if errutil.IsAuthError(err) {
if errors.IsAuthError(err) {
httputil.SetAuthType(cfg, req, res)
return Batch(cfg, objects, operation, transferAdapters)
}
switch res.StatusCode {
case 404, 410:
tracerx.Printf("api: batch not implemented: %d", res.StatusCode)
return nil, "", errutil.NewNotImplementedError(nil)
return nil, "", errors.NewNotImplementedError(errors.Errorf("api: batch not implemented: %d", res.StatusCode))
}
tracerx.Printf("api error: %s", err)
return nil, "", errutil.Error(err)
return nil, "", errors.Wrap(err, "batch response")
}
httputil.LogTransfer(cfg, "lfs.batch", res)
if res.StatusCode != 200 {
return nil, "", errutil.Error(fmt.Errorf("Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode))
return nil, "", errors.Errorf("Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode)
}
return bresp.Objects, bresp.TransferAdapterName, nil
@ -140,7 +138,7 @@ func Legacy(cfg *config.Configuration, objects []*ObjectResource, operation stri
func DownloadCheck(cfg *config.Configuration, oid string) (*ObjectResource, error) {
req, err := NewRequest(cfg, "GET", oid)
if err != nil {
return nil, errutil.Error(err)
return nil, errors.Wrap(err, "download check")
}
res, obj, err := DoLegacyRequest(cfg, req)
@ -152,7 +150,7 @@ func DownloadCheck(cfg *config.Configuration, oid string) (*ObjectResource, erro
_, err = obj.NewRequest("download", "GET")
if err != nil {
return nil, errutil.Error(err)
return nil, errors.Wrap(err, "download check")
}
return obj, nil
@ -167,12 +165,12 @@ func UploadCheck(cfg *config.Configuration, oid string, size int64) (*ObjectReso
by, err := json.Marshal(reqObj)
if err != nil {
return nil, errutil.Error(err)
return nil, errors.Wrap(err, "upload check")
}
req, err := NewRequest(cfg, "POST", oid)
if err != nil {
return nil, errutil.Error(err)
return nil, errors.Wrap(err, "upload check")
}
req.Header.Set("Content-Type", MediaType)
@ -184,12 +182,12 @@ func UploadCheck(cfg *config.Configuration, oid string, size int64) (*ObjectReso
res, obj, err := DoLegacyRequest(cfg, req)
if err != nil {
if errutil.IsAuthError(err) {
if errors.IsAuthError(err) {
httputil.SetAuthType(cfg, req, res)
return UploadCheck(cfg, oid, size)
}
return nil, errutil.NewRetriableError(err)
return nil, errors.NewRetriableError(err)
}
httputil.LogTransfer(cfg, "lfs.upload", res)

@ -16,7 +16,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/auth"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/httputil"
)
@ -313,7 +313,7 @@ func TestDownloadAPIError(t *testing.T) {
t.Fatal("no error?")
}
if errutil.IsFatalError(err) {
if errors.IsFatalError(err) {
t.Fatal("should not panic")
}
@ -321,7 +321,7 @@ func TestDownloadAPIError(t *testing.T) {
return
}
expected := "LFS: " + fmt.Sprintf(httputil.GetDefaultError(404), server.URL+"/media/objects/oid")
expected := fmt.Sprintf(httputil.GetDefaultError(404), server.URL+"/media/objects/oid")
if err.Error() != expected {
t.Fatalf("Expected: %s\nGot: %s", expected, err.Error())
}

@ -15,7 +15,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/httputil"
"github.com/github/git-lfs/lfs"
"github.com/github/git-lfs/test"
@ -448,7 +448,7 @@ func TestUploadApiError(t *testing.T) {
t.Fatal(err)
}
if errutil.IsFatalError(err) {
if errors.IsFatalError(err) {
t.Fatal("should not panic")
}
@ -577,11 +577,11 @@ func TestUploadVerifyError(t *testing.T) {
t.Fatal("verify should fail")
}
if errutil.IsFatalError(err) {
if errors.IsFatalError(err) {
t.Fatal("should not panic")
}
expected := "LFS: " + fmt.Sprintf(httputil.GetDefaultError(404), server.URL+"/verify")
expected := fmt.Sprintf(httputil.GetDefaultError(404), server.URL+"/verify")
if err.Error() != expected {
t.Fatalf("Expected: %s\nGot: %s", expected, err.Error())
}

@ -7,7 +7,7 @@ import (
"github.com/github/git-lfs/auth"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/httputil"
"github.com/rubyist/tracerx"
@ -55,7 +55,7 @@ func DoBatchRequest(cfg *config.Configuration, req *http.Request) (*http.Respons
if err != nil {
if res != nil && res.StatusCode == 401 {
return res, nil, errutil.NewAuthError(err)
return res, nil, errors.NewAuthError(err)
}
return res, nil, err
}

@ -8,7 +8,7 @@ import (
"strconv"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/httputil"
)
@ -21,12 +21,12 @@ func VerifyUpload(cfg *config.Configuration, obj *ObjectResource) error {
req, err := obj.NewRequest("verify", "POST")
if err != nil {
return errutil.Error(err)
return errors.Wrap(err, "verify")
}
by, err := json.Marshal(obj)
if err != nil {
return errutil.Error(err)
return errors.Wrap(err, "verify")
}
req.Header.Set("Content-Type", MediaType)

@ -3,7 +3,6 @@ package auth
import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"net"
"net/http"
@ -13,7 +12,7 @@ import (
"strings"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/rubyist/tracerx"
)
@ -35,7 +34,7 @@ func GetCreds(cfg *config.Configuration, req *http.Request) (Creds, error) {
credsUrl, err := getCredURLForAPI(cfg, req)
if err != nil {
return nil, errutil.Error(err)
return nil, errors.Wrap(err, "creds")
}
if credsUrl == nil {

@ -7,7 +7,7 @@ import (
"os/exec"
"sync"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/git"
"github.com/github/git-lfs/lfs"
"github.com/github/git-lfs/progress"
@ -174,7 +174,7 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
// Check the content - either missing or still this pointer (not exist is ok)
filepointer, err := lfs.DecodePointerFromFile(pointer.Name)
if err != nil && !os.IsNotExist(err) {
if errutil.IsNotAPointerError(err) {
if errors.IsNotAPointerError(err) {
// File has non-pointer content, leave it alone
continue
}
@ -193,7 +193,7 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
err = lfs.PointerSmudgeToFile(cwdfilepath, pointer.Pointer, false, manifest, nil)
if err != nil {
if errutil.IsDownloadDeclinedError(err) {
if errors.IsDownloadDeclinedError(err) {
// acceptable error, data not local (fetch not run or include/exclude)
LoggedError(err, "Skipped checkout for %v, content not local. Use fetch to download.", pointer.Name)
} else {

@ -3,7 +3,7 @@ package commands
import (
"os"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/lfs"
"github.com/github/git-lfs/progress"
"github.com/spf13/cobra"
@ -43,8 +43,8 @@ func cleanCommand(cmd *cobra.Command, args []string) {
defer cleaned.Teardown()
}
if errutil.IsCleanPointerError(err) {
os.Stdout.Write(errutil.ErrorGetContext(err, "bytes").([]byte))
if errors.IsCleanPointerError(err) {
os.Stdout.Write(errors.GetContext(err, "bytes").([]byte))
return
}

@ -1,13 +1,12 @@
package commands
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/spf13/cobra"
)
@ -54,7 +53,7 @@ func logsClearCommand(cmd *cobra.Command, args []string) {
func logsBoomtownCommand(cmd *cobra.Command, args []string) {
Debug("Debug message")
err := errutil.Errorf(errors.New("Inner error message!"), "Error!")
err := errors.Wrapf(errors.New("Inner error message!"), "Error")
Panic(err, "Welcome to Boomtown")
Debug("Never seen")
}

@ -6,7 +6,7 @@ import (
"os"
"path/filepath"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/lfs"
"github.com/spf13/cobra"
)
@ -71,7 +71,7 @@ func smudgeCommand(cmd *cobra.Command, args []string) {
if err != nil {
ptr.Encode(os.Stdout)
// Download declined error is ok to skip if we weren't requesting download
if !(errutil.IsDownloadDeclinedError(err) && !download) {
if !(errors.IsDownloadDeclinedError(err) && !download) {
LoggedError(err, "Error downloading object: %s (%s)", filename, ptr.Oid)
if !cfg.SkipDownloadErrors() {
os.Exit(2)
@ -85,8 +85,8 @@ func smudgeFilename(args []string, err error) string {
return args[0]
}
if errutil.IsSmudgeError(err) {
return filepath.Base(errutil.ErrorGetContext(err, "FileName").(string))
if errors.IsSmudgeError(err) {
return filepath.Base(errors.GetContext(err, "FileName").(string))
}
return "<unknown file>"

@ -14,7 +14,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/git"
"github.com/github/git-lfs/httputil"
"github.com/github/git-lfs/lfs"
@ -85,18 +85,21 @@ func TransferManifest() *transfer.Manifest {
// Error prints a formatted message to Stderr. It also gets printed to the
// panic log if one is created for this command.
func Error(format string, args ...interface{}) {
line := format
if len(args) > 0 {
line = fmt.Sprintf(format, args...)
if len(args) == 0 {
fmt.Fprintln(ErrorWriter, format)
return
}
fmt.Fprintln(ErrorWriter, line)
fmt.Fprintf(ErrorWriter, format+"\n", args...)
}
// Print prints a formatted message to Stdout. It also gets printed to the
// panic log if one is created for this command.
func Print(format string, args ...interface{}) {
line := fmt.Sprintf(format, args...)
fmt.Fprintln(OutputWriter, line)
if len(args) == 0 {
fmt.Fprintln(OutputWriter, format)
return
}
fmt.Fprintf(OutputWriter, format+"\n", args...)
}
// Exit prints a formatted message and exits.
@ -118,21 +121,12 @@ func FullError(err error) {
}
func errorWith(err error, fatalErrFn func(error, string, ...interface{}), errFn func(string, ...interface{})) {
var innermsg string
if inner := errutil.GetInnerError(err); inner != nil {
innermsg = inner.Error()
if Debugging || errors.IsFatalError(err) {
fatalErrFn(err, "")
return
}
errmsg := err.Error()
if errmsg != innermsg {
Error(innermsg)
}
if Debugging || errutil.IsFatalError(err) {
fatalErrFn(err, errmsg)
} else {
errFn(errmsg)
}
errFn("%s", err)
}
// Debug prints a formatted message if debugging is enabled. The formatted
@ -147,7 +141,9 @@ func Debug(format string, args ...interface{}) {
// LoggedError prints a formatted message to Stderr and writes a stack trace for
// the error to a log file without exiting.
func LoggedError(err error, format string, args ...interface{}) {
if len(format) > 0 {
Error(format, args...)
}
file := handlePanic(err)
if len(file) > 0 {
@ -260,17 +256,15 @@ func logPanicToWriter(w io.Writer, loggedError error) {
w.Write(ErrorBuffer.Bytes())
fmt.Fprintln(w)
fmt.Fprintln(w, loggedError.Error())
fmt.Fprintf(w, "%s\n", loggedError)
for _, stackline := range errors.StackTrace(loggedError) {
fmt.Fprintln(w, stackline)
}
if err, ok := loggedError.(ErrorWithStack); ok {
fmt.Fprintln(w, err.InnerError())
for key, value := range err.Context() {
fmt.Fprintf(w, "%s=%s\n", key, value)
}
w.Write(err.Stack())
} else {
w.Write(errutil.Stack())
for key, val := range errors.Context(err) {
fmt.Fprintf(w, "%s=%v\n", key, val)
}
fmt.Fprintln(w, "\nENV:")
// log the environment
@ -279,12 +273,6 @@ func logPanicToWriter(w io.Writer, loggedError error) {
}
}
type ErrorWithStack interface {
Context() map[string]string
InnerError() string
Stack() []byte
}
func determineIncludeExcludePaths(config *config.Configuration, includeArg, excludeArg *string) (include, exclude []string) {
if includeArg == nil {
include = config.FetchIncludePaths()

@ -3,7 +3,7 @@ package commands
import (
"os"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/lfs"
"github.com/github/git-lfs/tools"
)
@ -129,8 +129,8 @@ func upload(c *uploadContext, unfiltered []*lfs.WrappedPointer) {
for _, p := range pointers {
u, err := lfs.NewUploadable(p.Oid, p.Name)
if err != nil {
if errutil.IsCleanPointerError(err) {
Exit(uploadMissingErr, p.Oid, p.Name, errutil.ErrorGetContext(err, "pointer").(*lfs.Pointer).Oid)
if errors.IsCleanPointerError(err) {
Exit(uploadMissingErr, p.Oid, p.Name, errors.GetContext(err, "pointer").(*lfs.Pointer).Oid)
} else {
ExitWithError(err)
}

42
errors/context.go Normal file

@ -0,0 +1,42 @@
package errors
type withContext interface {
Set(string, interface{})
Get(string) interface{}
Del(string)
Context() map[string]interface{}
}
// ErrorSetContext sets a value in the error's context. If the error has not
// been wrapped, it does nothing.
func SetContext(err error, key string, value interface{}) {
if e, ok := err.(withContext); ok {
e.Set(key, value)
}
}
// ErrorGetContext gets a value from the error's context. If the error has not
// been wrapped, it returns an empty string.
func GetContext(err error, key string) interface{} {
if e, ok := err.(withContext); ok {
return e.Get(key)
}
return ""
}
// ErrorDelContext removes a value from the error's context. If the error has
// not been wrapped, it does nothing.
func DelContext(err error, key string) {
if e, ok := err.(withContext); ok {
e.Del(key)
}
}
// ErrorContext returns the context map for an error if it is a wrappedError.
// If it is not a wrappedError it will return an empty map.
func Context(err error) map[string]interface{} {
if e, ok := err.(withContext); ok {
return e.Context()
}
return nil
}

102
errors/errors.go Normal file

@ -0,0 +1,102 @@
// Package errors provides common error handling tools
// NOTE: Subject to change, do not rely on this package from outside git-lfs source
package errors
// 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)
// }
//
// 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()
// errors.ErrorSetContext(err, "foo", "bar")
// errors.ErrorGetContext(err, "foo") // => "bar"
// errors.ErrorDelContext(err, "foo")
//
// Wrapped errors also contain the stack from the point at which they are
// 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
import (
"fmt"
"github.com/pkg/errors"
)
// 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)
}
// 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)
}
// Wrapf wraps an error with an additional formatted message.
func Wrapf(err error, format string, args ...interface{}) error {
if err == nil {
err = errors.New("")
}
message := fmt.Sprintf(format, args...)
return newWrappedError(err, message)
}
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
}

@ -1,4 +1,4 @@
package errutil
package errors
import (
"errors"
@ -45,9 +45,9 @@ func TestBehaviorWraps(t *testing.T) {
func TestContextOnGoErrors(t *testing.T) {
err := errors.New("Go error")
ErrorSetContext(err, "foo", "bar")
SetContext(err, "foo", "bar")
v := ErrorGetContext(err, "foo")
v := GetContext(err, "foo")
if v == "bar" {
t.Error("expected empty context on go error")
}
@ -56,20 +56,20 @@ func TestContextOnGoErrors(t *testing.T) {
func TestContextOnWrappedErrors(t *testing.T) {
err := NewFatalError(errors.New("Go error"))
ErrorSetContext(err, "foo", "bar")
SetContext(err, "foo", "bar")
if v := ErrorGetContext(err, "foo"); v != "bar" {
if v := GetContext(err, "foo"); v != "bar" {
t.Error("expected to be able to use context on wrapped errors")
}
ctxt := ErrorContext(err)
ctxt := Context(err)
if ctxt["foo"] != "bar" {
t.Error("expected to get the context of an error")
}
ErrorDelContext(err, "foo")
DelContext(err, "foo")
if v := ErrorGetContext(err, "foo"); v == "bar" {
if v := GetContext(err, "foo"); v == "bar" {
t.Errorf("expected to delete from error context")
}
}

@ -1,74 +1,11 @@
// Package errutil provides common error handling tools
// NOTE: Subject to change, do not rely on this package from outside git-lfs source
package errutil
// 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)
// }
//
// 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()
// errutil.ErrorSetContext(err, "foo", "bar")
// errutil.ErrorGetContext(err, "foo") // => "bar"
// errutil.ErrorDelContext(err, "foo")
//
// Wrapped errors also contain the stack from the point at which they are
// called. The stack is accessed via ErrorStack(). Calling ErrorStack() on a
// regular Go error will return an empty byte slice.
package errors
import (
"fmt"
"runtime"
"github.com/pkg/errors"
)
type errorWithCause interface {
Error() string
Cause() error
}
func parentOf(err error) error {
if c, ok := err.(errorWithCause); ok {
return c.Cause()
}
return nil
}
// IsFatalError indicates that the error is fatal and the process should exit
// immediately after handling the error.
func IsFatalError(err error) bool {
@ -111,34 +48,6 @@ func IsAuthError(err error) bool {
return false
}
// IsInvalidPointerError indicates an attempt to parse data that was not a
// valid pointer.
func IsInvalidPointerError(err error) bool {
if e, ok := err.(interface {
InvalidPointer() bool
}); ok {
return e.InvalidPointer()
}
if parent := parentOf(err); parent != nil {
return IsInvalidPointerError(parent)
}
return false
}
// IsInvalidRepoError indicates an operation was attempted from outside a git
// repository.
func IsInvalidRepoError(err error) bool {
if e, ok := err.(interface {
InvalidRepo() bool
}); ok {
return e.InvalidRepo()
}
if parent := parentOf(err); parent != nil {
return IsInvalidRepoError(parent)
}
return false
}
// IsSmudgeError indicates an error while smudging a files.
func IsSmudgeError(err error) bool {
if e, ok := err.(interface {
@ -231,74 +140,11 @@ func IsRetriableError(err error) bool {
return false
}
func GetInnerError(err error) error {
if parent := parentOf(err); parent != nil {
return parent
}
return nil
}
// Error wraps an error with an empty message.
func Error(err error) error {
return Errorf(err, "")
}
// Errorf wraps an error with an additional formatted message.
func Errorf(err error, format string, args ...interface{}) error {
if err == nil {
err = errors.New("")
}
message := ""
if len(format) > 0 {
message = fmt.Sprintf(format, args...)
}
return newWrappedError(err, message)
}
// ErrorSetContext sets a value in the error's context. If the error has not
// been wrapped, it does nothing.
func ErrorSetContext(err error, key string, value interface{}) {
if e, ok := err.(errorWrapper); ok {
e.Set(key, value)
}
}
// ErrorGetContext gets a value from the error's context. If the error has not
// been wrapped, it returns an empty string.
func ErrorGetContext(err error, key string) interface{} {
if e, ok := err.(errorWrapper); ok {
return e.Get(key)
}
return ""
}
// ErrorDelContext removes a value from the error's context. If the error has
// not been wrapped, it does nothing.
func ErrorDelContext(err error, key string) {
if e, ok := err.(errorWrapper); ok {
e.Del(key)
}
}
// ErrorContext returns the context map for an error if it is a wrappedError.
// If it is not a wrappedError it will return an empty map.
func ErrorContext(err error) map[string]interface{} {
if e, ok := err.(errorWrapper); ok {
return e.Context()
}
return nil
}
type errorWrapper interface {
errorWithCause
Set(string, interface{})
Get(string) interface{}
Del(string)
Context() map[string]interface{}
type errorWithCause interface {
Cause() error
StackTrace() errors.StackTrace
error
fmt.Formatter
}
// wrappedError is the base error wrapper. It provides a Message string, a
@ -309,7 +155,7 @@ type wrappedError struct {
}
// newWrappedError creates a wrappedError.
func newWrappedError(err error, message string) errorWrapper {
func newWrappedError(err error, message string) *wrappedError {
if err == nil {
err = errors.New("Error")
}
@ -353,7 +199,7 @@ func (e wrappedError) Context() map[string]interface{} {
// Definitions for IsFatalError()
type fatalError struct {
errorWrapper
*wrappedError
}
func (e fatalError) Fatal() bool {
@ -367,7 +213,7 @@ func NewFatalError(err error) error {
// Definitions for IsNotImplementedError()
type notImplementedError struct {
errorWrapper
*wrappedError
}
func (e notImplementedError) NotImplemented() bool {
@ -381,7 +227,7 @@ func NewNotImplementedError(err error) error {
// Definitions for IsAuthError()
type authError struct {
errorWrapper
*wrappedError
}
func (e authError) AuthError() bool {
@ -392,38 +238,10 @@ func NewAuthError(err error) error {
return authError{newWrappedError(err, "Authentication required")}
}
// Definitions for IsInvalidPointerError()
type invalidPointerError struct {
errorWrapper
}
func (e invalidPointerError) InvalidPointer() bool {
return true
}
func NewInvalidPointerError(err error) error {
return invalidPointerError{newWrappedError(err, "Invalid pointer")}
}
// Definitions for IsInvalidRepoError()
type invalidRepoError struct {
errorWrapper
}
func (e invalidRepoError) InvalidRepo() bool {
return true
}
func NewInvalidRepoError(err error) error {
return invalidRepoError{newWrappedError(err, "Not in a git repository")}
}
// Definitions for IsSmudgeError()
type smudgeError struct {
errorWrapper
*wrappedError
}
func (e smudgeError) SmudgeError() bool {
@ -432,32 +250,33 @@ func (e smudgeError) SmudgeError() bool {
func NewSmudgeError(err error, oid, filename string) error {
e := smudgeError{newWrappedError(err, "Smudge error")}
ErrorSetContext(e, "OID", oid)
ErrorSetContext(e, "FileName", filename)
SetContext(e, "OID", oid)
SetContext(e, "FileName", filename)
return e
}
// Definitions for IsCleanPointerError()
type cleanPointerError struct {
errorWrapper
*wrappedError
}
func (e cleanPointerError) CleanPointerError() bool {
return true
}
func NewCleanPointerError(err error, pointer interface{}, bytes []byte) error {
e := cleanPointerError{newWrappedError(err, "Clean pointer error")}
ErrorSetContext(e, "pointer", pointer)
ErrorSetContext(e, "bytes", bytes)
func NewCleanPointerError(pointer interface{}, bytes []byte) error {
err := New("pointer error")
e := cleanPointerError{newWrappedError(err, "clean")}
SetContext(e, "pointer", pointer)
SetContext(e, "bytes", bytes)
return e
}
// Definitions for IsNotAPointerError()
type notAPointerError struct {
errorWrapper
*wrappedError
}
func (e notAPointerError) NotAPointerError() bool {
@ -472,7 +291,7 @@ type badPointerKeyError struct {
Expected string
Actual string
errorWrapper
*wrappedError
}
func (e badPointerKeyError) BadPointerKeyError() bool {
@ -480,28 +299,28 @@ func (e badPointerKeyError) BadPointerKeyError() bool {
}
func NewBadPointerKeyError(expected, actual string) error {
err := fmt.Errorf("Error parsing LFS Pointer. Expected key %s, got %s", expected, actual)
return badPointerKeyError{expected, actual, newWrappedError(err, "")}
err := Errorf("Expected key %s, got %s", expected, actual)
return badPointerKeyError{expected, actual, newWrappedError(err, "pointer parsing")}
}
// Definitions for IsDownloadDeclinedError()
type downloadDeclinedError struct {
errorWrapper
*wrappedError
}
func (e downloadDeclinedError) DownloadDeclinedError() bool {
return true
}
func NewDownloadDeclinedError(err error) error {
return downloadDeclinedError{newWrappedError(err, "File missing and download is not allowed")}
func NewDownloadDeclinedError(err error, msg string) error {
return downloadDeclinedError{newWrappedError(err, msg)}
}
// Definitions for IsRetriableError()
type retriableError struct {
errorWrapper
*wrappedError
}
func (e retriableError) RetriableError() bool {
@ -512,9 +331,10 @@ func NewRetriableError(err error) error {
return retriableError{newWrappedError(err, "")}
}
// Stack returns a byte slice containing the runtime.Stack()
func Stack() []byte {
stackBuf := make([]byte, 1024*1024)
written := runtime.Stack(stackBuf, false)
return stackBuf[:written]
func parentOf(err error) error {
if c, ok := err.(errorWithCause); ok {
return c.Cause()
}
return nil
}

@ -10,7 +10,7 @@ import (
"github.com/github/git-lfs/auth"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/rubyist/tracerx"
)
@ -46,12 +46,15 @@ func (e *ClientError) Error() string {
func doHttpRequest(cfg *config.Configuration, req *http.Request, creds auth.Creds) (*http.Response, error) {
var (
res *http.Response
cause string
err error
)
if cfg.NtlmAccess(auth.GetOperationForRequest(req)) {
cause = "ntlm"
res, err = doNTLMRequest(cfg, req, true)
} else {
cause = "http"
res, err = NewHttpClient(cfg, req.Host).Do(req)
}
@ -65,11 +68,11 @@ func doHttpRequest(cfg *config.Configuration, req *http.Request, creds auth.Cred
}
if err != nil {
if errutil.IsAuthError(err) {
if errors.IsAuthError(err) {
SetAuthType(cfg, req, res)
doHttpRequest(cfg, req, creds)
} else {
err = errutil.Error(err)
err = errors.Wrap(err, cause)
}
} else {
err = handleResponse(cfg, res, creds)
@ -126,7 +129,7 @@ func DoHttpRequestWithRedirects(cfg *config.Configuration, req *http.Request, vi
redirectedReq, err := NewHttpRequest(req.Method, redirectTo, nil)
if err != nil {
return res, errutil.Errorf(err, err.Error())
return res, errors.Wrapf(err, err.Error())
}
via = append(via, req)
@ -139,17 +142,17 @@ func DoHttpRequestWithRedirects(cfg *config.Configuration, req *http.Request, vi
seeker, ok := realBody.(io.Seeker)
if !ok {
return res, errutil.Errorf(nil, "Request body needs to be an io.Seeker to handle redirects.")
return res, errors.Wrapf(nil, "Request body needs to be an io.Seeker to handle redirects.")
}
if _, err := seeker.Seek(0, 0); err != nil {
return res, errutil.Error(err)
return res, errors.Wrap(err, "request retry")
}
redirectedReq.Body = realBody
redirectedReq.ContentLength = req.ContentLength
if err = CheckRedirect(redirectedReq, via); err != nil {
return res, errutil.Errorf(err, err.Error())
return res, errors.Wrapf(err, err.Error())
}
return DoHttpRequestWithRedirects(cfg, redirectedReq, via, useCreds)

@ -11,7 +11,7 @@ import (
"testing"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
)
func TestSuccessStatus(t *testing.T) {
@ -77,7 +77,7 @@ func TestErrorStatusWithCustomMessage(t *testing.T) {
continue
}
if errutil.IsFatalError(err) == (panicMsg != "panic") {
if errors.IsFatalError(err) == (panicMsg != "panic") {
t.Errorf("Error for HTTP %d should %s", status, panicMsg)
continue
}
@ -140,7 +140,7 @@ func TestErrorStatusWithDefaultMessage(t *testing.T) {
continue
}
if errutil.IsFatalError(err) == (results[1] != "panic") {
if errors.IsFatalError(err) == (results[1] != "panic") {
t.Errorf("Error for HTTP %d should %s", status, results[1])
continue
}

@ -10,7 +10,7 @@ import (
"github.com/github/git-lfs/auth"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
)
var (
@ -41,7 +41,7 @@ func DecodeResponse(res *http.Response, obj interface{}) error {
res.Body.Close()
if err != nil {
return errutil.Errorf(err, "Unable to parse HTTP response for %s", TraceHttpReq(res.Request))
return errors.Wrapf(err, "Unable to parse HTTP response for %s", TraceHttpReq(res.Request))
}
return nil
@ -74,16 +74,22 @@ func handleResponse(cfg *config.Configuration, res *http.Response, creds auth.Cr
if len(cliErr.Message) == 0 {
err = defaultError(res)
} else {
err = errutil.Error(cliErr)
err = errors.Wrap(cliErr, "http")
}
}
if res.StatusCode == 401 {
return errutil.NewAuthError(err)
if err == nil {
err = errors.New("api: received status 401")
}
return errors.NewAuthError(err)
}
if res.StatusCode > 499 && res.StatusCode != 501 && res.StatusCode != 509 {
return errutil.NewFatalError(err)
if err == nil {
err = errors.Errorf("api: received status %d", res.StatusCode)
}
return errors.NewFatalError(err)
}
return err
@ -100,18 +106,18 @@ func defaultError(res *http.Response) error {
msgFmt = defaultErrors[500] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
}
return errutil.Error(fmt.Errorf(msgFmt, res.Request.URL))
return errors.Errorf(msgFmt, res.Request.URL)
}
func SetErrorResponseContext(cfg *config.Configuration, err error, res *http.Response) {
errutil.ErrorSetContext(err, "Status", res.Status)
errors.SetContext(err, "Status", res.Status)
setErrorHeaderContext(err, "Request", res.Header)
setErrorRequestContext(cfg, err, res.Request)
}
func setErrorRequestContext(cfg *config.Configuration, err error, req *http.Request) {
errutil.ErrorSetContext(err, "Endpoint", cfg.Endpoint(auth.GetOperationForRequest(req)).Url)
errutil.ErrorSetContext(err, "URL", TraceHttpReq(req))
errors.SetContext(err, "Endpoint", cfg.Endpoint(auth.GetOperationForRequest(req)).Url)
errors.SetContext(err, "URL", TraceHttpReq(req))
setErrorHeaderContext(err, "Response", req.Header)
}
@ -119,9 +125,9 @@ func setErrorHeaderContext(err error, prefix string, head http.Header) {
for key, _ := range head {
contextKey := fmt.Sprintf("%s:%s", prefix, key)
if _, skip := hiddenHeaders[key]; skip {
errutil.ErrorSetContext(err, contextKey, "--")
errors.SetContext(err, contextKey, "--")
} else {
errutil.ErrorSetContext(err, contextKey, head.Get(key))
errors.SetContext(err, contextKey, head.Get(key))
}
}
}

@ -90,7 +90,7 @@ func (a *Attribute) set(key, value string, opt InstallOptions) error {
}
return err
} else if currentValue != value {
return fmt.Errorf("The %s attribute should be \"%s\" but is \"%s\"",
return fmt.Errorf("The %s attribute should be %q but is %q",
key, value, currentValue)
}

@ -9,7 +9,7 @@ import (
"strings"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/git"
)
@ -90,7 +90,7 @@ func (h *Hook) Upgrade() error {
// or any of the past versions of this hook.
func (h *Hook) Uninstall() error {
if !InRepo() {
return errutil.NewInvalidRepoError(nil)
return errors.New("Not in a git repository")
}
match, err := h.matchesCurrent()

@ -11,10 +11,9 @@ import (
"strconv"
"strings"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/progress"
"github.com/github/git-lfs/transfer"
"github.com/pkg/errors"
)
var (
@ -95,7 +94,7 @@ func DecodePointerFromFile(file string) (*Pointer, error) {
return nil, err
}
if stat.Size() > blobSizeCutoff {
return nil, errutil.NewNotAPointerError(errors.New("file size exceeds lfs pointer size cutoff"))
return nil, errors.NewNotAPointerError(errors.New("file size exceeds lfs pointer size cutoff"))
}
f, err := os.OpenFile(file, os.O_RDONLY, 0644)
if err != nil {
@ -124,7 +123,7 @@ func DecodeFrom(reader io.Reader) ([]byte, *Pointer, error) {
func verifyVersion(version string) error {
if len(version) == 0 {
return errutil.NewNotAPointerError(errors.New("Missing version"))
return errors.NewNotAPointerError(errors.New("Missing version"))
}
for _, v := range v1Aliases {
@ -139,8 +138,8 @@ func verifyVersion(version string) error {
func decodeKV(data []byte) (*Pointer, error) {
kvps, exts, err := decodeKVData(data)
if err != nil {
if errutil.IsBadPointerKeyError(err) {
return nil, errutil.StandardizeBadPointerError(err)
if errors.IsBadPointerKeyError(err) {
return nil, errors.StandardizeBadPointerError(err)
}
return nil, err
}
@ -234,7 +233,7 @@ func decodeKVData(data []byte) (kvps map[string]string, exts map[string]string,
kvps = make(map[string]string)
if !matcherRE.Match(data) {
err = errutil.NewNotAPointerError(errors.New("invalid header"))
err = errors.NewNotAPointerError(errors.New("invalid header"))
return
}
@ -263,7 +262,7 @@ func decodeKVData(data []byte) (kvps map[string]string, exts map[string]string,
if expected := pointerKeys[line]; key != expected {
if !extRE.Match([]byte(key)) {
err = errutil.NewBadPointerKeyError(expected, key)
err = errors.NewBadPointerKeyError(expected, key)
return
}
if exts == nil {

@ -8,7 +8,7 @@ import (
"os"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/progress"
"github.com/github/git-lfs/tools"
)
@ -78,7 +78,7 @@ func copyToTemp(reader io.Reader, fileSize int64, cb progress.CopyCallback) (oid
by, ptr, err := DecodeFrom(reader)
if err == nil && len(by) < 512 {
err = errutil.NewCleanPointerError(err, ptr, by)
err = errors.NewCleanPointerError(ptr, by)
return
}

@ -12,7 +12,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/progress"
"github.com/rubyist/tracerx"
)
@ -25,7 +25,7 @@ func PointerSmudgeToFile(filename string, ptr *Pointer, download bool, manifest
}
defer file.Close()
if err := PointerSmudge(file, ptr, filename, download, manifest, cb); err != nil {
if errutil.IsDownloadDeclinedError(err) {
if errors.IsDownloadDeclinedError(err) {
// write placeholder data instead
file.Seek(0, os.SEEK_SET)
ptr.Encode(file)
@ -46,7 +46,6 @@ func PointerSmudge(writer io.Writer, ptr *Pointer, workingfile string, download
LinkOrCopyFromReference(ptr.Oid, ptr.Size)
stat, statErr := os.Stat(mediafile)
if statErr == nil && stat != nil {
fileSize := stat.Size()
if fileSize == 0 || fileSize != ptr.Size {
@ -60,14 +59,14 @@ func PointerSmudge(writer io.Writer, ptr *Pointer, workingfile string, download
if download {
err = downloadFile(writer, ptr, workingfile, mediafile, manifest, cb)
} else {
return errutil.NewDownloadDeclinedError(nil)
return errors.NewDownloadDeclinedError(statErr, "smudge")
}
} else {
err = readLocalFile(writer, ptr, mediafile, workingfile, cb)
}
if err != nil {
return errutil.NewSmudgeError(err, ptr.Oid, mediafile)
return errors.NewSmudgeError(err, ptr.Oid, mediafile)
}
return nil
@ -79,7 +78,7 @@ func downloadFile(writer io.Writer, ptr *Pointer, workingfile, mediafile string,
xfers := manifest.GetDownloadAdapterNames()
obj, adapterName, err := api.BatchOrLegacySingle(config.Config, &api.ObjectResource{Oid: ptr.Oid, Size: ptr.Size}, "download", xfers)
if err != nil {
return errutil.Errorf(err, "Error downloading %s: %s", filepath.Base(mediafile), err)
return errors.Wrapf(err, "Error downloading %s: %s", filepath.Base(mediafile), err)
}
if ptr.Size == 0 {
@ -104,7 +103,7 @@ func downloadFile(writer io.Writer, ptr *Pointer, workingfile, mediafile string,
res := <-adapterResultChan
if res.Error != nil {
return errutil.Errorf(err, "Error buffering media file: %s", res.Error)
return errors.Wrapf(err, "Error buffering media file: %s", res.Error)
}
return readLocalFile(writer, ptr, mediafile, workingfile, nil)
@ -113,7 +112,7 @@ func downloadFile(writer io.Writer, ptr *Pointer, workingfile, mediafile string,
func readLocalFile(writer io.Writer, ptr *Pointer, mediafile string, workingfile string, cb progress.CopyCallback) error {
reader, err := os.Open(mediafile)
if err != nil {
return errutil.Errorf(err, "Error opening media file.")
return errors.Wrapf(err, "Error opening media file.")
}
defer reader.Close()
@ -130,14 +129,14 @@ func readLocalFile(writer io.Writer, ptr *Pointer, mediafile string, workingfile
ext, ok := registeredExts[ptrExt.Name]
if !ok {
err := fmt.Errorf("Extension '%s' is not configured.", ptrExt.Name)
return errutil.Error(err)
return errors.Wrap(err, "smudge")
}
ext.Priority = ptrExt.Priority
extensions[ext.Name] = ext
}
exts, err := config.SortExtensions(extensions)
if err != nil {
return errutil.Error(err)
return errors.Wrap(err, "smudge")
}
// pipe extensions in reverse order
@ -151,7 +150,7 @@ func readLocalFile(writer io.Writer, ptr *Pointer, mediafile string, workingfile
response, err := pipeExtensions(request)
if err != nil {
return errutil.Error(err)
return errors.Wrap(err, "smudge")
}
actualExts := make(map[string]*pipeExtResult)
@ -163,32 +162,32 @@ func readLocalFile(writer io.Writer, ptr *Pointer, mediafile string, workingfile
oid := response.results[0].oidIn
if ptr.Oid != oid {
err = fmt.Errorf("Actual oid %s during smudge does not match expected %s", oid, ptr.Oid)
return errutil.Error(err)
return errors.Wrap(err, "smudge")
}
for _, expected := range ptr.Extensions {
actual := actualExts[expected.Name]
if actual.name != expected.Name {
err = fmt.Errorf("Actual extension name '%s' does not match expected '%s'", actual.name, expected.Name)
return errutil.Error(err)
return errors.Wrap(err, "smudge")
}
if actual.oidOut != expected.Oid {
err = fmt.Errorf("Actual oid %s for extension '%s' does not match expected %s", actual.oidOut, expected.Name, expected.Oid)
return errutil.Error(err)
return errors.Wrap(err, "smudge")
}
}
// setup reader
reader, err = os.Open(response.file.Name())
if err != nil {
return errutil.Errorf(err, "Error opening smudged file: %s", err)
return errors.Wrapf(err, "Error opening smudged file: %s", err)
}
defer reader.Close()
}
_, err = tools.CopyWithCallback(writer, reader, ptr.Size, cb)
if err != nil {
return errutil.Errorf(err, "Error reading from media file: %s", err)
return errors.Wrapf(err, "Error reading from media file: %s", err)
}
return nil

@ -8,7 +8,7 @@ import (
"strings"
"testing"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/stretchr/testify/assert"
)
@ -81,7 +81,7 @@ func TestDecodeTinyFile(t *testing.T) {
t.Errorf("pointer was decoded: %v", p)
}
if !errutil.IsNotAPointerError(err) {
if !errors.IsNotAPointerError(err) {
t.Errorf("error is not a NotAPointerError: %s: '%v'", reflect.TypeOf(err), err)
}
}

@ -6,7 +6,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/git"
"github.com/github/git-lfs/progress"
"github.com/github/git-lfs/transfer"
@ -355,7 +355,7 @@ func (q *TransferQueue) batchApiRoutine() {
objs, adapterName, err := api.Batch(config.Config, transfers, q.transferKind(), transferAdapterNames)
if err != nil {
if errutil.IsNotImplementedError(err) {
if errors.IsNotImplementedError(err) {
git.Config.SetLocal("", "lfs.batch", "false")
go q.legacyFallback(batch)
@ -379,7 +379,7 @@ func (q *TransferQueue) batchApiRoutine() {
for _, o := range objs {
if o.Error != nil {
q.errorc <- errutil.Errorf(o.Error, "[%v] %v", o.Oid, o.Error.Message)
q.errorc <- errors.Wrapf(o.Error, "[%v] %v", o.Oid, o.Error.Message)
q.Skip(o.Size)
q.wait.Done()
continue
@ -461,7 +461,7 @@ func (q *TransferQueue) retry(t Transferable) {
}
func (q *TransferQueue) canRetry(err error) bool {
if !errutil.IsRetriableError(err) || atomic.LoadUint32(&q.retrying) == 1 {
if !errors.IsRetriableError(err) || atomic.LoadUint32(&q.retrying) == 1 {
return false
}

@ -7,7 +7,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/transfer"
)
@ -54,7 +54,7 @@ func (u *Uploadable) LegacyCheck() (*api.ObjectResource, error) {
func NewUploadable(oid, filename string) (*Uploadable, error) {
localMediaPath, err := LocalMediaPath(oid)
if err != nil {
return nil, errutil.Errorf(err, "Error uploading file %s (%s)", filename, oid)
return nil, errors.Wrapf(err, "Error uploading file %s (%s)", filename, oid)
}
if len(filename) > 0 {
@ -65,7 +65,7 @@ func NewUploadable(oid, filename string) (*Uploadable, error) {
fi, err := os.Stat(localMediaPath)
if err != nil {
return nil, errutil.Errorf(err, "Error uploading file %s (%s)", filename, oid)
return nil, errors.Wrapf(err, "Error uploading file %s (%s)", filename, oid)
}
return &Uploadable{oid: oid, OidPath: localMediaPath, Filename: filename, size: fi.Size()}, nil

@ -12,7 +12,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/lfs"
"github.com/github/git-lfs/test"
"github.com/spf13/cobra"
@ -170,7 +170,7 @@ func buildTestData() (oidsExist, oidsMissing []TestObject, err error) {
uploadQueue.Wait()
for _, err := range uploadQueue.Errors() {
if errutil.IsFatalError(err) {
if errors.IsFatalError(err) {
exit("Fatal error setting up test data: %s", err)
}
}

@ -5,7 +5,7 @@ import (
"sync"
"time"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/rubyist/tracerx"
)
@ -128,7 +128,7 @@ func (a *adapterBase) worker(workerNum int, ctx interface{}) {
var err error
if t.Object.IsExpired(time.Now().Add(objectExpirationGracePeriod)) {
tracerx.Printf("xfer: adapter %q worker %d found job for %q expired, retrying...", a.Name(), workerNum, t.Object.Oid)
err = errutil.NewRetriableError(fmt.Errorf("lfs/transfer: object %q has expired", t.Object.Oid))
err = errors.NewRetriableError(errors.Errorf("lfs/transfer: object %q has expired", t.Object.Oid))
} else if t.Object.Size < 0 {
tracerx.Printf("xfer: adapter %q worker %d found invalid size for %q (got: %d), retrying...", a.Name(), workerNum, t.Object.Oid, t.Object.Size)
err = fmt.Errorf("Git LFS: object %q has invalid size (got: %d)", t.Object.Oid, t.Object.Size)

@ -1,7 +1,6 @@
package transfer
import (
"errors"
"fmt"
"hash"
"io"
@ -11,7 +10,7 @@ import (
"strconv"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/httputil"
"github.com/github/git-lfs/localstorage"
"github.com/github/git-lfs/tools"
@ -119,7 +118,7 @@ func (a *basicDownloadAdapter) download(t *Transfer, cb TransferProgressCallback
os.Remove(dlFile.Name())
return a.download(t, cb, authOkFunc, nil, 0, nil)
}
return errutil.NewRetriableError(err)
return errors.NewRetriableError(err)
}
httputil.LogTransfer(config.Config, "lfs.data.download", res)
defer res.Body.Close()

@ -10,7 +10,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/httputil"
"github.com/github/git-lfs/progress"
)
@ -69,7 +69,7 @@ func (a *basicUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb Transfe
f, err := os.OpenFile(t.Path, os.O_RDONLY, 0644)
if err != nil {
return errutil.Error(err)
return errors.Wrap(err, "basic upload")
}
defer f.Close()
@ -99,18 +99,19 @@ func (a *basicUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb Transfe
res, err := httputil.DoHttpRequest(config.Config, req, t.Object.NeedsAuth())
if err != nil {
return errutil.NewRetriableError(err)
return errors.NewRetriableError(err)
}
httputil.LogTransfer(config.Config, "lfs.data.upload", res)
// A status code of 403 likely means that an authentication token for the
// upload has expired. This can be safely retried.
if res.StatusCode == 403 {
return errutil.NewRetriableError(err)
err = errors.New("http: received status 403")
return errors.NewRetriableError(err)
}
if res.StatusCode > 299 {
return errutil.Errorf(nil, "Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode)
return errors.Wrapf(nil, "Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode)
}
io.Copy(ioutil.Discard, res.Body)

@ -9,7 +9,7 @@ import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errutil"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/httputil"
"github.com/github/git-lfs/progress"
"github.com/rubyist/tracerx"
@ -55,7 +55,7 @@ func (a *tusUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb TransferP
req.Header.Set("Tus-Resumable", TusVersion)
res, err := httputil.DoHttpRequest(config.Config, req, false)
if err != nil {
return errutil.NewRetriableError(err)
return errors.NewRetriableError(err)
}
// Response will contain Upload-Offset if supported
@ -78,7 +78,7 @@ func (a *tusUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb TransferP
// Open file for uploading
f, err := os.OpenFile(t.Path, os.O_RDONLY, 0644)
if err != nil {
return errutil.Error(err)
return errors.Wrap(err, "tus upload")
}
defer f.Close()
@ -90,7 +90,7 @@ func (a *tusUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb TransferP
advanceCallbackProgress(cb, t, offset)
_, err := f.Seek(offset, os.SEEK_CUR)
if err != nil {
return errutil.Error(err)
return errors.Wrap(err, "tus upload")
}
}
@ -136,18 +136,19 @@ func (a *tusUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb TransferP
res, err = httputil.DoHttpRequest(config.Config, req, false)
if err != nil {
return errutil.NewRetriableError(err)
return errors.NewRetriableError(err)
}
httputil.LogTransfer(config.Config, "lfs.data.upload", res)
// A status code of 403 likely means that an authentication token for the
// upload has expired. This can be safely retried.
if res.StatusCode == 403 {
return errutil.NewRetriableError(err)
err = errors.New("http: received status 403")
return errors.NewRetriableError(err)
}
if res.StatusCode > 299 {
return errutil.Errorf(nil, "Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode)
return errors.Wrapf(nil, "Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode)
}
io.Copy(ioutil.Discard, res.Body)