full diff: https://github.com/pkg/errors/compare/v0.8.1...v0.9.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
... | ... |
@@ -152,7 +152,7 @@ github.com/prometheus/client_model d1d2010b5beead3fa1c5f271a5cf |
152 | 152 |
github.com/prometheus/common 287d3e634a1e550c9e463dd7e5a75a422c614505 # v0.7.0 |
153 | 153 |
github.com/prometheus/procfs 6d489fc7f1d9cd890a250f3ea3431b1744b9623f # v0.0.8 |
154 | 154 |
github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1 |
155 |
-github.com/pkg/errors ba968bfe8b2f7e042a574c888954fccecfa385b4 # v0.8.1 |
|
155 |
+github.com/pkg/errors 614d223910a179a466c1767a985424175c39b465 # v0.9.1 |
|
156 | 156 |
github.com/grpc-ecosystem/go-grpc-prometheus c225b8c3b01faf2899099b768856a9e916e5087b # v1.2.0 |
157 | 157 |
github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1 |
158 | 158 |
|
... | ... |
@@ -41,11 +41,18 @@ default: |
41 | 41 |
|
42 | 42 |
[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors). |
43 | 43 |
|
44 |
+## Roadmap |
|
45 |
+ |
|
46 |
+With the upcoming [Go2 error proposals](https://go.googlesource.com/proposal/+/master/design/go2draft.md) this package is moving into maintenance mode. The roadmap for a 1.0 release is as follows: |
|
47 |
+ |
|
48 |
+- 0.9. Remove pre Go 1.9 and Go 1.10 support, address outstanding pull requests (if possible) |
|
49 |
+- 1.0. Final release. |
|
50 |
+ |
|
44 | 51 |
## Contributing |
45 | 52 |
|
46 |
-We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high. |
|
53 |
+Because of the Go2 errors changes, this package is not accepting proposals for new functionality. With that said, we welcome pull requests, bug fixes and issue reports. |
|
47 | 54 |
|
48 |
-Before proposing a change, please discuss your change by raising an issue. |
|
55 |
+Before sending a PR, please discuss your change by raising an issue. |
|
49 | 56 |
|
50 | 57 |
## License |
51 | 58 |
|
... | ... |
@@ -82,7 +82,7 @@ |
82 | 82 |
// |
83 | 83 |
// if err, ok := err.(stackTracer); ok { |
84 | 84 |
// for _, f := range err.StackTrace() { |
85 |
-// fmt.Printf("%+s:%d", f) |
|
85 |
+// fmt.Printf("%+s:%d\n", f, f) |
|
86 | 86 |
// } |
87 | 87 |
// } |
88 | 88 |
// |
... | ... |
@@ -159,6 +159,9 @@ type withStack struct { |
159 | 159 |
|
160 | 160 |
func (w *withStack) Cause() error { return w.error } |
161 | 161 |
|
162 |
+// Unwrap provides compatibility for Go 1.13 error chains. |
|
163 |
+func (w *withStack) Unwrap() error { return w.error } |
|
164 |
+ |
|
162 | 165 |
func (w *withStack) Format(s fmt.State, verb rune) { |
163 | 166 |
switch verb { |
164 | 167 |
case 'v': |
... | ... |
@@ -241,6 +244,9 @@ type withMessage struct { |
241 | 241 |
func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() } |
242 | 242 |
func (w *withMessage) Cause() error { return w.cause } |
243 | 243 |
|
244 |
+// Unwrap provides compatibility for Go 1.13 error chains. |
|
245 |
+func (w *withMessage) Unwrap() error { return w.cause } |
|
246 |
+ |
|
244 | 247 |
func (w *withMessage) Format(s fmt.State, verb rune) { |
245 | 248 |
switch verb { |
246 | 249 |
case 'v': |
247 | 250 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,38 @@ |
0 |
+// +build go1.13 |
|
1 |
+ |
|
2 |
+package errors |
|
3 |
+ |
|
4 |
+import ( |
|
5 |
+ stderrors "errors" |
|
6 |
+) |
|
7 |
+ |
|
8 |
+// Is reports whether any error in err's chain matches target. |
|
9 |
+// |
|
10 |
+// The chain consists of err itself followed by the sequence of errors obtained by |
|
11 |
+// repeatedly calling Unwrap. |
|
12 |
+// |
|
13 |
+// An error is considered to match a target if it is equal to that target or if |
|
14 |
+// it implements a method Is(error) bool such that Is(target) returns true. |
|
15 |
+func Is(err, target error) bool { return stderrors.Is(err, target) } |
|
16 |
+ |
|
17 |
+// As finds the first error in err's chain that matches target, and if so, sets |
|
18 |
+// target to that error value and returns true. |
|
19 |
+// |
|
20 |
+// The chain consists of err itself followed by the sequence of errors obtained by |
|
21 |
+// repeatedly calling Unwrap. |
|
22 |
+// |
|
23 |
+// An error matches target if the error's concrete value is assignable to the value |
|
24 |
+// pointed to by target, or if the error has a method As(interface{}) bool such that |
|
25 |
+// As(target) returns true. In the latter case, the As method is responsible for |
|
26 |
+// setting target. |
|
27 |
+// |
|
28 |
+// As will panic if target is not a non-nil pointer to either a type that implements |
|
29 |
+// error, or to any interface type. As returns false if err is nil. |
|
30 |
+func As(err error, target interface{}) bool { return stderrors.As(err, target) } |
|
31 |
+ |
|
32 |
+// Unwrap returns the result of calling the Unwrap method on err, if err's |
|
33 |
+// type contains an Unwrap method returning error. |
|
34 |
+// Otherwise, Unwrap returns nil. |
|
35 |
+func Unwrap(err error) error { |
|
36 |
+ return stderrors.Unwrap(err) |
|
37 |
+} |
... | ... |
@@ -5,10 +5,13 @@ import ( |
5 | 5 |
"io" |
6 | 6 |
"path" |
7 | 7 |
"runtime" |
8 |
+ "strconv" |
|
8 | 9 |
"strings" |
9 | 10 |
) |
10 | 11 |
|
11 | 12 |
// Frame represents a program counter inside a stack frame. |
13 |
+// For historical reasons if Frame is interpreted as a uintptr |
|
14 |
+// its value represents the program counter + 1. |
|
12 | 15 |
type Frame uintptr |
13 | 16 |
|
14 | 17 |
// pc returns the program counter for this frame; |
... | ... |
@@ -37,6 +40,15 @@ func (f Frame) line() int { |
37 | 37 |
return line |
38 | 38 |
} |
39 | 39 |
|
40 |
+// name returns the name of this function, if known. |
|
41 |
+func (f Frame) name() string { |
|
42 |
+ fn := runtime.FuncForPC(f.pc()) |
|
43 |
+ if fn == nil { |
|
44 |
+ return "unknown" |
|
45 |
+ } |
|
46 |
+ return fn.Name() |
|
47 |
+} |
|
48 |
+ |
|
40 | 49 |
// Format formats the frame according to the fmt.Formatter interface. |
41 | 50 |
// |
42 | 51 |
// %s source file |
... | ... |
@@ -54,22 +66,16 @@ func (f Frame) Format(s fmt.State, verb rune) { |
54 | 54 |
case 's': |
55 | 55 |
switch { |
56 | 56 |
case s.Flag('+'): |
57 |
- pc := f.pc() |
|
58 |
- fn := runtime.FuncForPC(pc) |
|
59 |
- if fn == nil { |
|
60 |
- io.WriteString(s, "unknown") |
|
61 |
- } else { |
|
62 |
- file, _ := fn.FileLine(pc) |
|
63 |
- fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file) |
|
64 |
- } |
|
57 |
+ io.WriteString(s, f.name()) |
|
58 |
+ io.WriteString(s, "\n\t") |
|
59 |
+ io.WriteString(s, f.file()) |
|
65 | 60 |
default: |
66 | 61 |
io.WriteString(s, path.Base(f.file())) |
67 | 62 |
} |
68 | 63 |
case 'd': |
69 |
- fmt.Fprintf(s, "%d", f.line()) |
|
64 |
+ io.WriteString(s, strconv.Itoa(f.line())) |
|
70 | 65 |
case 'n': |
71 |
- name := runtime.FuncForPC(f.pc()).Name() |
|
72 |
- io.WriteString(s, funcname(name)) |
|
66 |
+ io.WriteString(s, funcname(f.name())) |
|
73 | 67 |
case 'v': |
74 | 68 |
f.Format(s, 's') |
75 | 69 |
io.WriteString(s, ":") |
... | ... |
@@ -77,6 +83,16 @@ func (f Frame) Format(s fmt.State, verb rune) { |
77 | 77 |
} |
78 | 78 |
} |
79 | 79 |
|
80 |
+// MarshalText formats a stacktrace Frame as a text string. The output is the |
|
81 |
+// same as that of fmt.Sprintf("%+v", f), but without newlines or tabs. |
|
82 |
+func (f Frame) MarshalText() ([]byte, error) { |
|
83 |
+ name := f.name() |
|
84 |
+ if name == "unknown" { |
|
85 |
+ return []byte(name), nil |
|
86 |
+ } |
|
87 |
+ return []byte(fmt.Sprintf("%s %s:%d", name, f.file(), f.line())), nil |
|
88 |
+} |
|
89 |
+ |
|
80 | 90 |
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest). |
81 | 91 |
type StackTrace []Frame |
82 | 92 |
|
... | ... |
@@ -94,16 +110,30 @@ func (st StackTrace) Format(s fmt.State, verb rune) { |
94 | 94 |
switch { |
95 | 95 |
case s.Flag('+'): |
96 | 96 |
for _, f := range st { |
97 |
- fmt.Fprintf(s, "\n%+v", f) |
|
97 |
+ io.WriteString(s, "\n") |
|
98 |
+ f.Format(s, verb) |
|
98 | 99 |
} |
99 | 100 |
case s.Flag('#'): |
100 | 101 |
fmt.Fprintf(s, "%#v", []Frame(st)) |
101 | 102 |
default: |
102 |
- fmt.Fprintf(s, "%v", []Frame(st)) |
|
103 |
+ st.formatSlice(s, verb) |
|
103 | 104 |
} |
104 | 105 |
case 's': |
105 |
- fmt.Fprintf(s, "%s", []Frame(st)) |
|
106 |
+ st.formatSlice(s, verb) |
|
107 |
+ } |
|
108 |
+} |
|
109 |
+ |
|
110 |
+// formatSlice will format this StackTrace into the given buffer as a slice of |
|
111 |
+// Frame, only valid when called with '%s' or '%v'. |
|
112 |
+func (st StackTrace) formatSlice(s fmt.State, verb rune) { |
|
113 |
+ io.WriteString(s, "[") |
|
114 |
+ for i, f := range st { |
|
115 |
+ if i > 0 { |
|
116 |
+ io.WriteString(s, " ") |
|
117 |
+ } |
|
118 |
+ f.Format(s, verb) |
|
106 | 119 |
} |
120 |
+ io.WriteString(s, "]") |
|
107 | 121 |
} |
108 | 122 |
|
109 | 123 |
// stack represents a stack of program counters. |