162 lines
4.0 KiB
Go
162 lines
4.0 KiB
Go
|
// Copyright 2014 Canonical Ltd.
|
||
|
// Licensed under the LGPLv3, see LICENCE file for details.
|
||
|
|
||
|
package errors_test
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"runtime"
|
||
|
|
||
|
jc "github.com/juju/testing/checkers"
|
||
|
gc "gopkg.in/check.v1"
|
||
|
|
||
|
"github.com/juju/errors"
|
||
|
)
|
||
|
|
||
|
type errorsSuite struct{}
|
||
|
|
||
|
var _ = gc.Suite(&errorsSuite{})
|
||
|
|
||
|
var someErr = errors.New("some error") //err varSomeErr
|
||
|
|
||
|
func (*errorsSuite) TestErrorString(c *gc.C) {
|
||
|
for i, test := range []struct {
|
||
|
message string
|
||
|
generator func() error
|
||
|
expected string
|
||
|
}{
|
||
|
{
|
||
|
message: "uncomparable errors",
|
||
|
generator: func() error {
|
||
|
err := errors.Annotatef(newNonComparableError("uncomparable"), "annotation")
|
||
|
return errors.Annotatef(err, "another")
|
||
|
},
|
||
|
expected: "another: annotation: uncomparable",
|
||
|
}, {
|
||
|
message: "Errorf",
|
||
|
generator: func() error {
|
||
|
return errors.Errorf("first error")
|
||
|
},
|
||
|
expected: "first error",
|
||
|
}, {
|
||
|
message: "annotated error",
|
||
|
generator: func() error {
|
||
|
err := errors.Errorf("first error")
|
||
|
return errors.Annotatef(err, "annotation")
|
||
|
},
|
||
|
expected: "annotation: first error",
|
||
|
}, {
|
||
|
message: "test annotation format",
|
||
|
generator: func() error {
|
||
|
err := errors.Errorf("first %s", "error")
|
||
|
return errors.Annotatef(err, "%s", "annotation")
|
||
|
},
|
||
|
expected: "annotation: first error",
|
||
|
}, {
|
||
|
message: "wrapped error",
|
||
|
generator: func() error {
|
||
|
err := newError("first error")
|
||
|
return errors.Wrap(err, newError("detailed error"))
|
||
|
},
|
||
|
expected: "detailed error",
|
||
|
}, {
|
||
|
message: "wrapped annotated error",
|
||
|
generator: func() error {
|
||
|
err := errors.Errorf("first error")
|
||
|
err = errors.Annotatef(err, "annotated")
|
||
|
return errors.Wrap(err, fmt.Errorf("detailed error"))
|
||
|
},
|
||
|
expected: "detailed error",
|
||
|
}, {
|
||
|
message: "annotated wrapped error",
|
||
|
generator: func() error {
|
||
|
err := errors.Errorf("first error")
|
||
|
err = errors.Wrap(err, fmt.Errorf("detailed error"))
|
||
|
return errors.Annotatef(err, "annotated")
|
||
|
},
|
||
|
expected: "annotated: detailed error",
|
||
|
}, {
|
||
|
message: "traced, and annotated",
|
||
|
generator: func() error {
|
||
|
err := errors.New("first error")
|
||
|
err = errors.Trace(err)
|
||
|
err = errors.Annotate(err, "some context")
|
||
|
err = errors.Trace(err)
|
||
|
err = errors.Annotate(err, "more context")
|
||
|
return errors.Trace(err)
|
||
|
},
|
||
|
expected: "more context: some context: first error",
|
||
|
}, {
|
||
|
message: "traced, and annotated, masked and annotated",
|
||
|
generator: func() error {
|
||
|
err := errors.New("first error")
|
||
|
err = errors.Trace(err)
|
||
|
err = errors.Annotate(err, "some context")
|
||
|
err = errors.Maskf(err, "masked")
|
||
|
err = errors.Annotate(err, "more context")
|
||
|
return errors.Trace(err)
|
||
|
},
|
||
|
expected: "more context: masked: some context: first error",
|
||
|
},
|
||
|
} {
|
||
|
c.Logf("%v: %s", i, test.message)
|
||
|
err := test.generator()
|
||
|
ok := c.Check(err.Error(), gc.Equals, test.expected)
|
||
|
if !ok {
|
||
|
c.Logf("%#v", test.generator())
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type embed struct {
|
||
|
errors.Err
|
||
|
}
|
||
|
|
||
|
func newEmbed(format string, args ...interface{}) *embed {
|
||
|
err := &embed{errors.NewErr(format, args...)}
|
||
|
err.SetLocation(1)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (*errorsSuite) TestNewErr(c *gc.C) {
|
||
|
if runtime.Compiler == "gccgo" {
|
||
|
c.Skip("gccgo can't determine the location")
|
||
|
}
|
||
|
err := newEmbed("testing %d", 42) //err embedErr
|
||
|
c.Assert(err.Error(), gc.Equals, "testing 42")
|
||
|
c.Assert(errors.Cause(err), gc.Equals, err)
|
||
|
c.Assert(errors.Details(err), jc.Contains, tagToLocation["embedErr"].String())
|
||
|
}
|
||
|
|
||
|
var _ error = (*embed)(nil)
|
||
|
|
||
|
// This is an uncomparable error type, as it is a struct that supports the
|
||
|
// error interface (as opposed to a pointer type).
|
||
|
type error_ struct {
|
||
|
info string
|
||
|
slice []string
|
||
|
}
|
||
|
|
||
|
// Create a non-comparable error
|
||
|
func newNonComparableError(message string) error {
|
||
|
return error_{info: message}
|
||
|
}
|
||
|
|
||
|
func (e error_) Error() string {
|
||
|
return e.info
|
||
|
}
|
||
|
|
||
|
func newError(message string) error {
|
||
|
return testError{message}
|
||
|
}
|
||
|
|
||
|
// The testError is a value type error for ease of seeing results
|
||
|
// when the test fails.
|
||
|
type testError struct {
|
||
|
message string
|
||
|
}
|
||
|
|
||
|
func (e testError) Error() string {
|
||
|
return e.message
|
||
|
}
|