mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-10 22:49:13 +08:00
feat(debugerror)
License: MIT Signed-off-by: Brian Tiger Chow <brian@perfmode.com> impl errorf License: MIT Signed-off-by: Brian Tiger Chow <brian@perfmode.com> return a debug error License: MIT Signed-off-by: Brian Tiger Chow <brian@perfmode.com>
This commit is contained in:
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
@ -60,6 +60,10 @@
|
||||
"ImportPath": "github.com/coreos/go-semver/semver",
|
||||
"Rev": "6fe83ccda8fb9b7549c9ab4ba47f47858bc950aa"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/facebookgo/stackerr",
|
||||
"Rev": "060fbf9364c89acd41bf710e9e92915a90e7a5b5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gonuts/flag",
|
||||
"Rev": "741a6cbd37a30dedc93f817e7de6aaf0ca38a493"
|
||||
|
24
Godeps/_workspace/src/github.com/facebookgo/stackerr/.travis.yml
generated
vendored
Normal file
24
Godeps/_workspace/src/github.com/facebookgo/stackerr/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
- go get -v code.google.com/p/go.tools/cmd/vet
|
||||
- go get -v github.com/golang/lint/golint
|
||||
- go get -v code.google.com/p/go.tools/cmd/cover
|
||||
|
||||
install:
|
||||
- go install -race -v std
|
||||
- go get -race -t -v ./...
|
||||
- go install -race -v ./...
|
||||
|
||||
script:
|
||||
- go vet ./...
|
||||
- $HOME/gopath/bin/golint .
|
||||
- go test -cpu=2 -race -v ./...
|
||||
- go test -cpu=2 -covermode=atomic ./...
|
4
Godeps/_workspace/src/github.com/facebookgo/stackerr/readme.md
generated
vendored
Normal file
4
Godeps/_workspace/src/github.com/facebookgo/stackerr/readme.md
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
stackerr [](http://travis-ci.org/facebookgo/stackerr)
|
||||
========
|
||||
|
||||
Documentation: https://godoc.org/github.com/facebookgo/stackerr
|
97
Godeps/_workspace/src/github.com/facebookgo/stackerr/stackerr.go
generated
vendored
Normal file
97
Godeps/_workspace/src/github.com/facebookgo/stackerr/stackerr.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
// Package stackerr provides a way to augment errors with one or more stack
|
||||
// traces to allow for easier debugging.
|
||||
package stackerr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/facebookgo/stack"
|
||||
)
|
||||
|
||||
// Error provides the wrapper that adds multiple Stacks to an error. Each Stack
|
||||
// represents a location in code thru which this error was wrapped.
|
||||
type Error struct {
|
||||
multiStack *stack.Multi
|
||||
underlying error
|
||||
}
|
||||
|
||||
// Error provides a multi line error string that includes the stack trace.
|
||||
func (e *Error) Error() string {
|
||||
return fmt.Sprintf("%s\n%s", e.underlying, e.multiStack)
|
||||
}
|
||||
|
||||
// MultiStack identifies the locations this error was wrapped at.
|
||||
func (e *Error) MultiStack() *stack.Multi {
|
||||
return e.multiStack
|
||||
}
|
||||
|
||||
// Underlying returns the error that is being wrapped.
|
||||
func (e *Error) Underlying() error {
|
||||
return e.underlying
|
||||
}
|
||||
|
||||
type hasMultiStack interface {
|
||||
MultiStack() *stack.Multi
|
||||
}
|
||||
|
||||
// WrapSkip the error and add the current Stack. The argument skip is the
|
||||
// number of stack frames to ascend, with 0 identifying the caller of Wrap. If
|
||||
// the error to be wrapped has a MultiStack, the current stack will be added to
|
||||
// it. If the error to be wrapped is nil, a nil error is returned.
|
||||
func WrapSkip(err error, skip int) error {
|
||||
// nil errors are returned back as nil.
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// we're adding another Stack to an already wrapped error.
|
||||
if se, ok := err.(hasMultiStack); ok {
|
||||
se.MultiStack().AddCallers(skip + 1)
|
||||
return err
|
||||
}
|
||||
|
||||
// we're create a freshly wrapped error.
|
||||
return &Error{
|
||||
multiStack: stack.CallersMulti(skip + 1),
|
||||
underlying: err,
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap provides a convenience function that calls WrapSkip with skip=0. That
|
||||
// is, the Stack starts with the caller of Wrap.
|
||||
func Wrap(err error) error {
|
||||
return WrapSkip(err, 1)
|
||||
}
|
||||
|
||||
// New returns a new error that includes the Stack.
|
||||
func New(s string) error {
|
||||
return WrapSkip(errors.New(s), 1)
|
||||
}
|
||||
|
||||
// Newf formats and returns a new error that includes the Stack.
|
||||
func Newf(format string, args ...interface{}) error {
|
||||
return WrapSkip(fmt.Errorf(format, args...), 1)
|
||||
}
|
||||
|
||||
type hasUnderlying interface {
|
||||
Underlying() error
|
||||
}
|
||||
|
||||
// Underlying returns all the underlying errors by iteratively checking if the
|
||||
// error has an Underlying error. If e is nil, the returned slice will be nil.
|
||||
func Underlying(e error) []error {
|
||||
var errs []error
|
||||
for {
|
||||
if e == nil {
|
||||
return errs
|
||||
}
|
||||
errs = append(errs, e)
|
||||
|
||||
if eh, ok := e.(hasUnderlying); ok {
|
||||
e = eh.Underlying()
|
||||
} else {
|
||||
e = nil
|
||||
}
|
||||
}
|
||||
}
|
82
Godeps/_workspace/src/github.com/facebookgo/stackerr/stackerr_test.go
generated
vendored
Normal file
82
Godeps/_workspace/src/github.com/facebookgo/stackerr/stackerr_test.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
package stackerr_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/facebookgo/stackerr"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
const errStr = "foo bar baz"
|
||||
e := stackerr.New(errStr)
|
||||
matches := []string{
|
||||
errStr,
|
||||
"^github.com/facebookgo/stackerr/stackerr_test.go:15 +TestNew$",
|
||||
}
|
||||
match(t, e.Error(), matches)
|
||||
}
|
||||
|
||||
func TestNewf(t *testing.T) {
|
||||
const fmtStr = "%s 42"
|
||||
const errStr = "foo bar baz"
|
||||
e := stackerr.Newf(fmtStr, errStr)
|
||||
matches := []string{
|
||||
fmt.Sprintf(fmtStr, errStr),
|
||||
"^github.com/facebookgo/stackerr/stackerr_test.go:26 +TestNewf$",
|
||||
}
|
||||
match(t, e.Error(), matches)
|
||||
}
|
||||
|
||||
func TestWrap(t *testing.T) {
|
||||
const errStr = "foo bar baz"
|
||||
e := stackerr.Wrap(errors.New(errStr))
|
||||
matches := []string{
|
||||
errStr,
|
||||
"^github.com/facebookgo/stackerr/stackerr_test.go:36 +TestWrap$",
|
||||
}
|
||||
match(t, e.Error(), matches)
|
||||
}
|
||||
|
||||
func TestNilWrap(t *testing.T) {
|
||||
if stackerr.WrapSkip(nil, 1) != nil {
|
||||
t.Fatal("did not get nil error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoubleWrap(t *testing.T) {
|
||||
e := stackerr.New("")
|
||||
if stackerr.WrapSkip(e, 1) != e {
|
||||
t.Fatal("double wrap failure")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLog(t *testing.T) {
|
||||
t.Log(stackerr.New("hello"))
|
||||
}
|
||||
|
||||
func TestUnderlying(t *testing.T) {
|
||||
e1 := errors.New("")
|
||||
e2 := stackerr.Wrap(e1)
|
||||
errs := stackerr.Underlying(e2)
|
||||
if len(errs) != 2 || errs[0] != e2 || errs[1] != e1 {
|
||||
t.Fatal("failed Underlying")
|
||||
}
|
||||
}
|
||||
|
||||
func match(t testing.TB, s string, matches []string) {
|
||||
lines := strings.Split(s, "\n")
|
||||
for i, m := range matches {
|
||||
if !regexp.MustCompile(m).MatchString(lines[i]) {
|
||||
t.Fatalf(
|
||||
"did not find expected match \"%s\" on line %d in:\n%s",
|
||||
m,
|
||||
i,
|
||||
s,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -169,6 +169,7 @@ func (i *cmdInvocation) Parse(args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("config path is %s", configPath)
|
||||
|
||||
// this sets up the function that will initialize the config lazily.
|
||||
ctx := i.req.Context()
|
||||
|
@ -5,11 +5,11 @@ import (
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
"github.com/jbenet/go-ipfs/util/debugerror"
|
||||
)
|
||||
|
||||
var log = u.Logger("config")
|
||||
@ -129,7 +129,7 @@ func (i *Identity) DecodePrivateKey(passphrase string) (crypto.PrivateKey, error
|
||||
func Load(filename string) (*Config, error) {
|
||||
// if nothing is there, fail. User must run 'ipfs init'
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
return nil, errors.New("ipfs not initialized, please run 'ipfs init'")
|
||||
return nil, debugerror.New("ipfs not initialized, please run 'ipfs init'")
|
||||
}
|
||||
|
||||
var cfg Config
|
||||
|
30
util/debugerror/debugerror.go
Normal file
30
util/debugerror/debugerror.go
Normal file
@ -0,0 +1,30 @@
|
||||
// package debugerror provides a way to augment errors with additional
|
||||
// information to allow for easier debugging.
|
||||
package debugerror
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/facebookgo/stackerr"
|
||||
"github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
func Errorf(format string, a ...interface{}) error {
|
||||
return Wrap(fmt.Errorf(format, a...))
|
||||
}
|
||||
|
||||
// New returns an error that contains a stack trace (in debug mode)
|
||||
func New(s string) error {
|
||||
if util.Debug {
|
||||
return stackerr.New(s)
|
||||
}
|
||||
return errors.New(s)
|
||||
}
|
||||
|
||||
func Wrap(err error) error {
|
||||
if util.Debug {
|
||||
return stackerr.Wrap(err)
|
||||
}
|
||||
return err
|
||||
}
|
Reference in New Issue
Block a user