forked from TrueCloudLab/restic
Update pkg/errors to v0.8.0
This commit is contained in:
parent
1794bdc663
commit
3bbcf89105
6 changed files with 545 additions and 31 deletions
4
vendor/manifest
vendored
4
vendor/manifest
vendored
|
@ -34,8 +34,8 @@
|
||||||
{
|
{
|
||||||
"importpath": "github.com/pkg/errors",
|
"importpath": "github.com/pkg/errors",
|
||||||
"repository": "https://github.com/pkg/errors",
|
"repository": "https://github.com/pkg/errors",
|
||||||
"revision": "17b591df37844cde689f4d5813e5cea0927d8dd2",
|
"revision": "645ef00459ed84a119197bfb8d8205042c6df63d",
|
||||||
"branch": "master"
|
"branch": "HEAD"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"importpath": "github.com/pkg/profile",
|
"importpath": "github.com/pkg/profile",
|
||||||
|
|
37
vendor/src/github.com/pkg/errors/errors.go
vendored
37
vendor/src/github.com/pkg/errors/errors.go
vendored
|
@ -14,13 +14,18 @@
|
||||||
// Adding context to an error
|
// Adding context to an error
|
||||||
//
|
//
|
||||||
// The errors.Wrap function returns a new error that adds context to the
|
// The errors.Wrap function returns a new error that adds context to the
|
||||||
// original error. For example
|
// original error by recording a stack trace at the point Wrap is called,
|
||||||
|
// and the supplied message. For example
|
||||||
//
|
//
|
||||||
// _, err := ioutil.ReadAll(r)
|
// _, err := ioutil.ReadAll(r)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return errors.Wrap(err, "read failed")
|
// return errors.Wrap(err, "read failed")
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
// If additional control is required the errors.WithStack and errors.WithMessage
|
||||||
|
// functions destructure errors.Wrap into its component operations of annotating
|
||||||
|
// an error with a stack trace and an a message, respectively.
|
||||||
|
//
|
||||||
// Retrieving the cause of an error
|
// Retrieving the cause of an error
|
||||||
//
|
//
|
||||||
// Using errors.Wrap constructs a stack of errors, adding context to the
|
// Using errors.Wrap constructs a stack of errors, adding context to the
|
||||||
|
@ -134,6 +139,18 @@ func (f *fundamental) Format(s fmt.State, verb rune) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithStack annotates err with a stack trace at the point WithStack was called.
|
||||||
|
// If err is nil, WithStack returns nil.
|
||||||
|
func WithStack(err error) error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &withStack{
|
||||||
|
err,
|
||||||
|
callers(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type withStack struct {
|
type withStack struct {
|
||||||
error
|
error
|
||||||
*stack
|
*stack
|
||||||
|
@ -157,7 +174,8 @@ func (w *withStack) Format(s fmt.State, verb rune) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap returns an error annotating err with message.
|
// Wrap returns an error annotating err with a stack trace
|
||||||
|
// at the point Wrap is called, and the supplied message.
|
||||||
// If err is nil, Wrap returns nil.
|
// If err is nil, Wrap returns nil.
|
||||||
func Wrap(err error, message string) error {
|
func Wrap(err error, message string) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -173,7 +191,8 @@ func Wrap(err error, message string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapf returns an error annotating err with the format specifier.
|
// Wrapf returns an error annotating err with a stack trace
|
||||||
|
// at the point Wrapf is call, and the format specifier.
|
||||||
// If err is nil, Wrapf returns nil.
|
// If err is nil, Wrapf returns nil.
|
||||||
func Wrapf(err error, format string, args ...interface{}) error {
|
func Wrapf(err error, format string, args ...interface{}) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -189,6 +208,18 @@ func Wrapf(err error, format string, args ...interface{}) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithMessage annotates err with a new message.
|
||||||
|
// If err is nil, WithMessage returns nil.
|
||||||
|
func WithMessage(err error, message string) error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &withMessage{
|
||||||
|
cause: err,
|
||||||
|
msg: message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type withMessage struct {
|
type withMessage struct {
|
||||||
cause error
|
cause error
|
||||||
msg string
|
msg string
|
||||||
|
|
91
vendor/src/github.com/pkg/errors/errors_test.go
vendored
91
vendor/src/github.com/pkg/errors/errors_test.go
vendored
|
@ -84,6 +84,18 @@ func TestCause(t *testing.T) {
|
||||||
}, {
|
}, {
|
||||||
err: x, // return from errors.New
|
err: x, // return from errors.New
|
||||||
want: x,
|
want: x,
|
||||||
|
}, {
|
||||||
|
WithMessage(nil, "whoops"),
|
||||||
|
nil,
|
||||||
|
}, {
|
||||||
|
WithMessage(io.EOF, "whoops"),
|
||||||
|
io.EOF,
|
||||||
|
}, {
|
||||||
|
WithStack(nil),
|
||||||
|
nil,
|
||||||
|
}, {
|
||||||
|
WithStack(io.EOF),
|
||||||
|
io.EOF,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
|
@ -137,23 +149,78 @@ func TestErrorf(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWithStackNil(t *testing.T) {
|
||||||
|
got := WithStack(nil)
|
||||||
|
if got != nil {
|
||||||
|
t.Errorf("WithStack(nil): got %#v, expected nil", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithStack(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
err error
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{io.EOF, "EOF"},
|
||||||
|
{WithStack(io.EOF), "EOF"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
got := WithStack(tt.err).Error()
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("WithStack(%v): got: %v, want %v", tt.err, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithMessageNil(t *testing.T) {
|
||||||
|
got := WithMessage(nil, "no error")
|
||||||
|
if got != nil {
|
||||||
|
t.Errorf("WithMessage(nil, \"no error\"): got %#v, expected nil", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithMessage(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
err error
|
||||||
|
message string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{io.EOF, "read error", "read error: EOF"},
|
||||||
|
{WithMessage(io.EOF, "read error"), "client error", "client error: read error: EOF"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
got := WithMessage(tt.err, tt.message).Error()
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// errors.New, etc values are not expected to be compared by value
|
// errors.New, etc values are not expected to be compared by value
|
||||||
// but the change in errors#27 made them incomparable. Assert that
|
// but the change in errors#27 made them incomparable. Assert that
|
||||||
// various kinds of errors have a functional equality operator, even
|
// various kinds of errors have a functional equality operator, even
|
||||||
// if the result of that equality is always false.
|
// if the result of that equality is always false.
|
||||||
func TestErrorEquality(t *testing.T) {
|
func TestErrorEquality(t *testing.T) {
|
||||||
tests := []struct {
|
vals := []error{
|
||||||
err1, err2 error
|
nil,
|
||||||
}{
|
io.EOF,
|
||||||
{io.EOF, io.EOF},
|
errors.New("EOF"),
|
||||||
{io.EOF, nil},
|
New("EOF"),
|
||||||
{io.EOF, errors.New("EOF")},
|
Errorf("EOF"),
|
||||||
{io.EOF, New("EOF")},
|
Wrap(io.EOF, "EOF"),
|
||||||
{New("EOF"), New("EOF")},
|
Wrapf(io.EOF, "EOF%d", 2),
|
||||||
{New("EOF"), Errorf("EOF")},
|
WithMessage(nil, "whoops"),
|
||||||
{New("EOF"), Wrap(io.EOF, "EOF")},
|
WithMessage(io.EOF, "whoops"),
|
||||||
|
WithStack(io.EOF),
|
||||||
|
WithStack(nil),
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
|
||||||
_ = tt.err1 == tt.err2 // mustn't panic
|
for i := range vals {
|
||||||
|
for j := range vals {
|
||||||
|
_ = vals[i] == vals[j] // mustn't panic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
53
vendor/src/github.com/pkg/errors/example_test.go
vendored
53
vendor/src/github.com/pkg/errors/example_test.go
vendored
|
@ -35,6 +35,59 @@ func ExampleNew_printf() {
|
||||||
// /home/dfc/go/src/runtime/asm_amd64.s:2059
|
// /home/dfc/go/src/runtime/asm_amd64.s:2059
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleWithMessage() {
|
||||||
|
cause := errors.New("whoops")
|
||||||
|
err := errors.WithMessage(cause, "oh noes")
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output: oh noes: whoops
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleWithStack() {
|
||||||
|
cause := errors.New("whoops")
|
||||||
|
err := errors.WithStack(cause)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
// Output: whoops
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleWithStack_printf() {
|
||||||
|
cause := errors.New("whoops")
|
||||||
|
err := errors.WithStack(cause)
|
||||||
|
fmt.Printf("%+v", err)
|
||||||
|
|
||||||
|
// Example Output:
|
||||||
|
// whoops
|
||||||
|
// github.com/pkg/errors_test.ExampleWithStack_printf
|
||||||
|
// /home/fabstu/go/src/github.com/pkg/errors/example_test.go:55
|
||||||
|
// testing.runExample
|
||||||
|
// /usr/lib/go/src/testing/example.go:114
|
||||||
|
// testing.RunExamples
|
||||||
|
// /usr/lib/go/src/testing/example.go:38
|
||||||
|
// testing.(*M).Run
|
||||||
|
// /usr/lib/go/src/testing/testing.go:744
|
||||||
|
// main.main
|
||||||
|
// github.com/pkg/errors/_test/_testmain.go:106
|
||||||
|
// runtime.main
|
||||||
|
// /usr/lib/go/src/runtime/proc.go:183
|
||||||
|
// runtime.goexit
|
||||||
|
// /usr/lib/go/src/runtime/asm_amd64.s:2086
|
||||||
|
// github.com/pkg/errors_test.ExampleWithStack_printf
|
||||||
|
// /home/fabstu/go/src/github.com/pkg/errors/example_test.go:56
|
||||||
|
// testing.runExample
|
||||||
|
// /usr/lib/go/src/testing/example.go:114
|
||||||
|
// testing.RunExamples
|
||||||
|
// /usr/lib/go/src/testing/example.go:38
|
||||||
|
// testing.(*M).Run
|
||||||
|
// /usr/lib/go/src/testing/testing.go:744
|
||||||
|
// main.main
|
||||||
|
// github.com/pkg/errors/_test/_testmain.go:106
|
||||||
|
// runtime.main
|
||||||
|
// /usr/lib/go/src/runtime/proc.go:183
|
||||||
|
// runtime.goexit
|
||||||
|
// /usr/lib/go/src/runtime/asm_amd64.s:2086
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleWrap() {
|
func ExampleWrap() {
|
||||||
cause := errors.New("whoops")
|
cause := errors.New("whoops")
|
||||||
err := errors.Wrap(cause, "oh noes")
|
err := errors.Wrap(cause, "oh noes")
|
||||||
|
|
385
vendor/src/github.com/pkg/errors/format_test.go
vendored
385
vendor/src/github.com/pkg/errors/format_test.go
vendored
|
@ -1,6 +1,7 @@
|
||||||
package errors
|
package errors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -26,7 +27,7 @@ func TestFormatNew(t *testing.T) {
|
||||||
"%+v",
|
"%+v",
|
||||||
"error\n" +
|
"error\n" +
|
||||||
"github.com/pkg/errors.TestFormatNew\n" +
|
"github.com/pkg/errors.TestFormatNew\n" +
|
||||||
"\t.+/github.com/pkg/errors/format_test.go:25",
|
"\t.+/github.com/pkg/errors/format_test.go:26",
|
||||||
}, {
|
}, {
|
||||||
New("error"),
|
New("error"),
|
||||||
"%q",
|
"%q",
|
||||||
|
@ -56,7 +57,7 @@ func TestFormatErrorf(t *testing.T) {
|
||||||
"%+v",
|
"%+v",
|
||||||
"error\n" +
|
"error\n" +
|
||||||
"github.com/pkg/errors.TestFormatErrorf\n" +
|
"github.com/pkg/errors.TestFormatErrorf\n" +
|
||||||
"\t.+/github.com/pkg/errors/format_test.go:55",
|
"\t.+/github.com/pkg/errors/format_test.go:56",
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
|
@ -82,7 +83,7 @@ func TestFormatWrap(t *testing.T) {
|
||||||
"%+v",
|
"%+v",
|
||||||
"error\n" +
|
"error\n" +
|
||||||
"github.com/pkg/errors.TestFormatWrap\n" +
|
"github.com/pkg/errors.TestFormatWrap\n" +
|
||||||
"\t.+/github.com/pkg/errors/format_test.go:81",
|
"\t.+/github.com/pkg/errors/format_test.go:82",
|
||||||
}, {
|
}, {
|
||||||
Wrap(io.EOF, "error"),
|
Wrap(io.EOF, "error"),
|
||||||
"%s",
|
"%s",
|
||||||
|
@ -97,14 +98,14 @@ func TestFormatWrap(t *testing.T) {
|
||||||
"EOF\n" +
|
"EOF\n" +
|
||||||
"error\n" +
|
"error\n" +
|
||||||
"github.com/pkg/errors.TestFormatWrap\n" +
|
"github.com/pkg/errors.TestFormatWrap\n" +
|
||||||
"\t.+/github.com/pkg/errors/format_test.go:95",
|
"\t.+/github.com/pkg/errors/format_test.go:96",
|
||||||
}, {
|
}, {
|
||||||
Wrap(Wrap(io.EOF, "error1"), "error2"),
|
Wrap(Wrap(io.EOF, "error1"), "error2"),
|
||||||
"%+v",
|
"%+v",
|
||||||
"EOF\n" +
|
"EOF\n" +
|
||||||
"error1\n" +
|
"error1\n" +
|
||||||
"github.com/pkg/errors.TestFormatWrap\n" +
|
"github.com/pkg/errors.TestFormatWrap\n" +
|
||||||
"\t.+/github.com/pkg/errors/format_test.go:102\n",
|
"\t.+/github.com/pkg/errors/format_test.go:103\n",
|
||||||
}, {
|
}, {
|
||||||
Wrap(New("error with space"), "context"),
|
Wrap(New("error with space"), "context"),
|
||||||
"%q",
|
"%q",
|
||||||
|
@ -135,7 +136,7 @@ func TestFormatWrapf(t *testing.T) {
|
||||||
"EOF\n" +
|
"EOF\n" +
|
||||||
"error2\n" +
|
"error2\n" +
|
||||||
"github.com/pkg/errors.TestFormatWrapf\n" +
|
"github.com/pkg/errors.TestFormatWrapf\n" +
|
||||||
"\t.+/github.com/pkg/errors/format_test.go:133",
|
"\t.+/github.com/pkg/errors/format_test.go:134",
|
||||||
}, {
|
}, {
|
||||||
Wrapf(New("error"), "error%d", 2),
|
Wrapf(New("error"), "error%d", 2),
|
||||||
"%s",
|
"%s",
|
||||||
|
@ -149,7 +150,7 @@ func TestFormatWrapf(t *testing.T) {
|
||||||
"%+v",
|
"%+v",
|
||||||
"error\n" +
|
"error\n" +
|
||||||
"github.com/pkg/errors.TestFormatWrapf\n" +
|
"github.com/pkg/errors.TestFormatWrapf\n" +
|
||||||
"\t.+/github.com/pkg/errors/format_test.go:148",
|
"\t.+/github.com/pkg/errors/format_test.go:149",
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
|
@ -157,16 +158,378 @@ func TestFormatWrapf(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFormatWithStack(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
error
|
||||||
|
format string
|
||||||
|
want []string
|
||||||
|
}{{
|
||||||
|
WithStack(io.EOF),
|
||||||
|
"%s",
|
||||||
|
[]string{"EOF"},
|
||||||
|
}, {
|
||||||
|
WithStack(io.EOF),
|
||||||
|
"%v",
|
||||||
|
[]string{"EOF"},
|
||||||
|
}, {
|
||||||
|
WithStack(io.EOF),
|
||||||
|
"%+v",
|
||||||
|
[]string{"EOF",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:175"},
|
||||||
|
}, {
|
||||||
|
WithStack(New("error")),
|
||||||
|
"%s",
|
||||||
|
[]string{"error"},
|
||||||
|
}, {
|
||||||
|
WithStack(New("error")),
|
||||||
|
"%v",
|
||||||
|
[]string{"error"},
|
||||||
|
}, {
|
||||||
|
WithStack(New("error")),
|
||||||
|
"%+v",
|
||||||
|
[]string{"error",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:189",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:189"},
|
||||||
|
}, {
|
||||||
|
WithStack(WithStack(io.EOF)),
|
||||||
|
"%+v",
|
||||||
|
[]string{"EOF",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:197",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:197"},
|
||||||
|
}, {
|
||||||
|
WithStack(WithStack(Wrapf(io.EOF, "message"))),
|
||||||
|
"%+v",
|
||||||
|
[]string{"EOF",
|
||||||
|
"message",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:205",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:205",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:205"},
|
||||||
|
}, {
|
||||||
|
WithStack(Errorf("error%d", 1)),
|
||||||
|
"%+v",
|
||||||
|
[]string{"error1",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:216",
|
||||||
|
"github.com/pkg/errors.TestFormatWithStack\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:216"},
|
||||||
|
}}
|
||||||
|
|
||||||
|
for i, tt := range tests {
|
||||||
|
testFormatCompleteCompare(t, i, tt.error, tt.format, tt.want, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFormatWithMessage(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
error
|
||||||
|
format string
|
||||||
|
want []string
|
||||||
|
}{{
|
||||||
|
WithMessage(New("error"), "error2"),
|
||||||
|
"%s",
|
||||||
|
[]string{"error2: error"},
|
||||||
|
}, {
|
||||||
|
WithMessage(New("error"), "error2"),
|
||||||
|
"%v",
|
||||||
|
[]string{"error2: error"},
|
||||||
|
}, {
|
||||||
|
WithMessage(New("error"), "error2"),
|
||||||
|
"%+v",
|
||||||
|
[]string{
|
||||||
|
"error",
|
||||||
|
"github.com/pkg/errors.TestFormatWithMessage\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:244",
|
||||||
|
"error2"},
|
||||||
|
}, {
|
||||||
|
WithMessage(io.EOF, "addition1"),
|
||||||
|
"%s",
|
||||||
|
[]string{"addition1: EOF"},
|
||||||
|
}, {
|
||||||
|
WithMessage(io.EOF, "addition1"),
|
||||||
|
"%v",
|
||||||
|
[]string{"addition1: EOF"},
|
||||||
|
}, {
|
||||||
|
WithMessage(io.EOF, "addition1"),
|
||||||
|
"%+v",
|
||||||
|
[]string{"EOF", "addition1"},
|
||||||
|
}, {
|
||||||
|
WithMessage(WithMessage(io.EOF, "addition1"), "addition2"),
|
||||||
|
"%v",
|
||||||
|
[]string{"addition2: addition1: EOF"},
|
||||||
|
}, {
|
||||||
|
WithMessage(WithMessage(io.EOF, "addition1"), "addition2"),
|
||||||
|
"%+v",
|
||||||
|
[]string{"EOF", "addition1", "addition2"},
|
||||||
|
}, {
|
||||||
|
Wrap(WithMessage(io.EOF, "error1"), "error2"),
|
||||||
|
"%+v",
|
||||||
|
[]string{"EOF", "error1", "error2",
|
||||||
|
"github.com/pkg/errors.TestFormatWithMessage\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:272"},
|
||||||
|
}, {
|
||||||
|
WithMessage(Errorf("error%d", 1), "error2"),
|
||||||
|
"%+v",
|
||||||
|
[]string{"error1",
|
||||||
|
"github.com/pkg/errors.TestFormatWithMessage\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:278",
|
||||||
|
"error2"},
|
||||||
|
}, {
|
||||||
|
WithMessage(WithStack(io.EOF), "error"),
|
||||||
|
"%+v",
|
||||||
|
[]string{
|
||||||
|
"EOF",
|
||||||
|
"github.com/pkg/errors.TestFormatWithMessage\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:285",
|
||||||
|
"error"},
|
||||||
|
}, {
|
||||||
|
WithMessage(Wrap(WithStack(io.EOF), "inside-error"), "outside-error"),
|
||||||
|
"%+v",
|
||||||
|
[]string{
|
||||||
|
"EOF",
|
||||||
|
"github.com/pkg/errors.TestFormatWithMessage\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:293",
|
||||||
|
"inside-error",
|
||||||
|
"github.com/pkg/errors.TestFormatWithMessage\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:293",
|
||||||
|
"outside-error"},
|
||||||
|
}}
|
||||||
|
|
||||||
|
for i, tt := range tests {
|
||||||
|
testFormatCompleteCompare(t, i, tt.error, tt.format, tt.want, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFormatGeneric(t *testing.T) {
|
||||||
|
starts := []struct {
|
||||||
|
err error
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{New("new-error"), []string{
|
||||||
|
"new-error",
|
||||||
|
"github.com/pkg/errors.TestFormatGeneric\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:315"},
|
||||||
|
}, {Errorf("errorf-error"), []string{
|
||||||
|
"errorf-error",
|
||||||
|
"github.com/pkg/errors.TestFormatGeneric\n" +
|
||||||
|
"\t.+/github.com/pkg/errors/format_test.go:319"},
|
||||||
|
}, {errors.New("errors-new-error"), []string{
|
||||||
|
"errors-new-error"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
wrappers := []wrapper{
|
||||||
|
{
|
||||||
|
func(err error) error { return WithMessage(err, "with-message") },
|
||||||
|
[]string{"with-message"},
|
||||||
|
}, {
|
||||||
|
func(err error) error { return WithStack(err) },
|
||||||
|
[]string{
|
||||||
|
"github.com/pkg/errors.(func·002|TestFormatGeneric.func2)\n\t" +
|
||||||
|
".+/github.com/pkg/errors/format_test.go:333",
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
func(err error) error { return Wrap(err, "wrap-error") },
|
||||||
|
[]string{
|
||||||
|
"wrap-error",
|
||||||
|
"github.com/pkg/errors.(func·003|TestFormatGeneric.func3)\n\t" +
|
||||||
|
".+/github.com/pkg/errors/format_test.go:339",
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
func(err error) error { return Wrapf(err, "wrapf-error%d", 1) },
|
||||||
|
[]string{
|
||||||
|
"wrapf-error1",
|
||||||
|
"github.com/pkg/errors.(func·004|TestFormatGeneric.func4)\n\t" +
|
||||||
|
".+/github.com/pkg/errors/format_test.go:346",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for s := range starts {
|
||||||
|
err := starts[s].err
|
||||||
|
want := starts[s].want
|
||||||
|
testFormatCompleteCompare(t, s, err, "%+v", want, false)
|
||||||
|
testGenericRecursive(t, err, want, wrappers, 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testFormatRegexp(t *testing.T, n int, arg interface{}, format, want string) {
|
func testFormatRegexp(t *testing.T, n int, arg interface{}, format, want string) {
|
||||||
got := fmt.Sprintf(format, arg)
|
got := fmt.Sprintf(format, arg)
|
||||||
lines := strings.SplitN(got, "\n", -1)
|
gotLines := strings.SplitN(got, "\n", -1)
|
||||||
for i, w := range strings.SplitN(want, "\n", -1) {
|
wantLines := strings.SplitN(want, "\n", -1)
|
||||||
match, err := regexp.MatchString(w, lines[i])
|
|
||||||
|
if len(wantLines) > len(gotLines) {
|
||||||
|
t.Errorf("test %d: wantLines(%d) > gotLines(%d):\n got: %q\nwant: %q", n+1, len(wantLines), len(gotLines), got, want)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, w := range wantLines {
|
||||||
|
match, err := regexp.MatchString(w, gotLines[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if !match {
|
if !match {
|
||||||
t.Errorf("test %d: line %d: fmt.Sprintf(%q, err): got: %q, want: %q", n+1, i+1, format, got, want)
|
t.Errorf("test %d: line %d: fmt.Sprintf(%q, err):\n got: %q\nwant: %q", n+1, i+1, format, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var stackLineR = regexp.MustCompile(`\.`)
|
||||||
|
|
||||||
|
// parseBlocks parses input into a slice, where:
|
||||||
|
// - incase entry contains a newline, its a stacktrace
|
||||||
|
// - incase entry contains no newline, its a solo line.
|
||||||
|
//
|
||||||
|
// Detecting stack boundaries only works incase the WithStack-calls are
|
||||||
|
// to be found on the same line, thats why it is optionally here.
|
||||||
|
//
|
||||||
|
// Example use:
|
||||||
|
//
|
||||||
|
// for _, e := range blocks {
|
||||||
|
// if strings.ContainsAny(e, "\n") {
|
||||||
|
// // Match as stack
|
||||||
|
// } else {
|
||||||
|
// // Match as line
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
func parseBlocks(input string, detectStackboundaries bool) ([]string, error) {
|
||||||
|
var blocks []string
|
||||||
|
|
||||||
|
stack := ""
|
||||||
|
wasStack := false
|
||||||
|
lines := map[string]bool{} // already found lines
|
||||||
|
|
||||||
|
for _, l := range strings.Split(input, "\n") {
|
||||||
|
isStackLine := stackLineR.MatchString(l)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case !isStackLine && wasStack:
|
||||||
|
blocks = append(blocks, stack, l)
|
||||||
|
stack = ""
|
||||||
|
lines = map[string]bool{}
|
||||||
|
case isStackLine:
|
||||||
|
if wasStack {
|
||||||
|
// Detecting two stacks after another, possible cause lines match in
|
||||||
|
// our tests due to WithStack(WithStack(io.EOF)) on same line.
|
||||||
|
if detectStackboundaries {
|
||||||
|
if lines[l] {
|
||||||
|
if len(stack) == 0 {
|
||||||
|
return nil, errors.New("len of block must not be zero here")
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks = append(blocks, stack)
|
||||||
|
stack = l
|
||||||
|
lines = map[string]bool{l: true}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stack = stack + "\n" + l
|
||||||
|
} else {
|
||||||
|
stack = l
|
||||||
|
}
|
||||||
|
lines[l] = true
|
||||||
|
case !isStackLine && !wasStack:
|
||||||
|
blocks = append(blocks, l)
|
||||||
|
default:
|
||||||
|
return nil, errors.New("must not happen")
|
||||||
|
}
|
||||||
|
|
||||||
|
wasStack = isStackLine
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use up stack
|
||||||
|
if stack != "" {
|
||||||
|
blocks = append(blocks, stack)
|
||||||
|
}
|
||||||
|
return blocks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFormatCompleteCompare(t *testing.T, n int, arg interface{}, format string, want []string, detectStackBoundaries bool) {
|
||||||
|
gotStr := fmt.Sprintf(format, arg)
|
||||||
|
|
||||||
|
got, err := parseBlocks(gotStr, detectStackBoundaries)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(got) != len(want) {
|
||||||
|
t.Fatalf("test %d: fmt.Sprintf(%s, err) -> wrong number of blocks: got(%d) want(%d)\n got: %s\nwant: %s\ngotStr: %q",
|
||||||
|
n+1, format, len(got), len(want), prettyBlocks(got), prettyBlocks(want), gotStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range got {
|
||||||
|
if strings.ContainsAny(want[i], "\n") {
|
||||||
|
// Match as stack
|
||||||
|
match, err := regexp.MatchString(want[i], got[i])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !match {
|
||||||
|
t.Fatalf("test %d: block %d: fmt.Sprintf(%q, err):\ngot:\n%q\nwant:\n%q\nall-got:\n%s\nall-want:\n%s\n",
|
||||||
|
n+1, i+1, format, got[i], want[i], prettyBlocks(got), prettyBlocks(want))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Match as message
|
||||||
|
if got[i] != want[i] {
|
||||||
|
t.Fatalf("test %d: fmt.Sprintf(%s, err) at block %d got != want:\n got: %q\nwant: %q", n+1, format, i+1, got[i], want[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type wrapper struct {
|
||||||
|
wrap func(err error) error
|
||||||
|
want []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func prettyBlocks(blocks []string, prefix ...string) string {
|
||||||
|
var out []string
|
||||||
|
|
||||||
|
for _, b := range blocks {
|
||||||
|
out = append(out, fmt.Sprintf("%v", b))
|
||||||
|
}
|
||||||
|
|
||||||
|
return " " + strings.Join(out, "\n ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGenericRecursive(t *testing.T, beforeErr error, beforeWant []string, list []wrapper, maxDepth int) {
|
||||||
|
if len(beforeWant) == 0 {
|
||||||
|
panic("beforeWant must not be empty")
|
||||||
|
}
|
||||||
|
for _, w := range list {
|
||||||
|
if len(w.want) == 0 {
|
||||||
|
panic("want must not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.wrap(beforeErr)
|
||||||
|
|
||||||
|
// Copy required cause append(beforeWant, ..) modified beforeWant subtly.
|
||||||
|
beforeCopy := make([]string, len(beforeWant))
|
||||||
|
copy(beforeCopy, beforeWant)
|
||||||
|
|
||||||
|
beforeWant := beforeCopy
|
||||||
|
last := len(beforeWant) - 1
|
||||||
|
var want []string
|
||||||
|
|
||||||
|
// Merge two stacks behind each other.
|
||||||
|
if strings.ContainsAny(beforeWant[last], "\n") && strings.ContainsAny(w.want[0], "\n") {
|
||||||
|
want = append(beforeWant[:last], append([]string{beforeWant[last] + "((?s).*)" + w.want[0]}, w.want[1:]...)...)
|
||||||
|
} else {
|
||||||
|
want = append(beforeWant, w.want...)
|
||||||
|
}
|
||||||
|
|
||||||
|
testFormatCompleteCompare(t, maxDepth, err, "%+v", want, false)
|
||||||
|
if maxDepth > 0 {
|
||||||
|
testGenericRecursive(t, err, want, list, maxDepth-1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,7 @@ func TestStackTrace(t *testing.T) {
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
func() error { return New("ooh") }(), []string{
|
func() error { return New("ooh") }(), []string{
|
||||||
`github.com/pkg/errors.(func·005|TestStackTrace.func1)` +
|
`github.com/pkg/errors.(func·009|TestStackTrace.func1)` +
|
||||||
"\n\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New
|
"\n\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New
|
||||||
"github.com/pkg/errors.TestStackTrace\n" +
|
"github.com/pkg/errors.TestStackTrace\n" +
|
||||||
"\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New's caller
|
"\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New's caller
|
||||||
|
@ -196,9 +196,9 @@ func TestStackTrace(t *testing.T) {
|
||||||
return Errorf("hello %s", fmt.Sprintf("world"))
|
return Errorf("hello %s", fmt.Sprintf("world"))
|
||||||
}()
|
}()
|
||||||
}()), []string{
|
}()), []string{
|
||||||
`github.com/pkg/errors.(func·006|TestStackTrace.func2.1)` +
|
`github.com/pkg/errors.(func·010|TestStackTrace.func2.1)` +
|
||||||
"\n\t.+/github.com/pkg/errors/stack_test.go:196", // this is the stack of Errorf
|
"\n\t.+/github.com/pkg/errors/stack_test.go:196", // this is the stack of Errorf
|
||||||
`github.com/pkg/errors.(func·007|TestStackTrace.func2)` +
|
`github.com/pkg/errors.(func·011|TestStackTrace.func2)` +
|
||||||
"\n\t.+/github.com/pkg/errors/stack_test.go:197", // this is the stack of Errorf's caller
|
"\n\t.+/github.com/pkg/errors/stack_test.go:197", // this is the stack of Errorf's caller
|
||||||
"github.com/pkg/errors.TestStackTrace\n" +
|
"github.com/pkg/errors.TestStackTrace\n" +
|
||||||
"\t.+/github.com/pkg/errors/stack_test.go:198", // this is the stack of Errorf's caller's caller
|
"\t.+/github.com/pkg/errors/stack_test.go:198", // this is the stack of Errorf's caller's caller
|
||||||
|
|
Loading…
Add table
Reference in a new issue