Skip to content
This repository was archived by the owner on Dec 1, 2021. It is now read-only.

Commit 785921b

Browse files
committed
Destructure New/Errorf
Destructure New/Errorf into two components, a call to the stdlib errors.New or fmt.Errorf to generate a _fundamental_ error, and then a call to withStack to attach a stack trace to the message.
1 parent 2a9be18 commit 785921b

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

errors.go

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,50 +87,49 @@
8787
package errors
8888

8989
import (
90+
"errors"
9091
"fmt"
9192
"io"
9293
)
9394

94-
// _error is an error implementation returned by New and Errorf
95-
// that implements its own fmt.Formatter.
96-
type _error struct {
97-
msg string
98-
*stack
99-
}
100-
101-
func (e _error) Error() string { return e.msg }
102-
103-
func (e _error) Format(s fmt.State, verb rune) {
104-
switch verb {
105-
case 'v':
106-
if s.Flag('+') {
107-
io.WriteString(s, e.msg)
108-
fmt.Fprintf(s, "%+v", e.StackTrace())
109-
return
110-
}
111-
fallthrough
112-
case 's':
113-
io.WriteString(s, e.msg)
114-
}
115-
}
116-
11795
// New returns an error with the supplied message.
11896
func New(message string) error {
119-
return _error{
120-
message,
97+
err := errors.New(message)
98+
return &withStack{
99+
err,
121100
callers(),
122101
}
123102
}
124103

125104
// Errorf formats according to a format specifier and returns the string
126105
// as a value that satisfies error.
127106
func Errorf(format string, args ...interface{}) error {
128-
return _error{
129-
fmt.Sprintf(format, args...),
107+
err := fmt.Errorf(format, args...)
108+
return &withStack{
109+
err,
130110
callers(),
131111
}
132112
}
133113

114+
type withStack struct {
115+
error
116+
*stack
117+
}
118+
119+
func (w *withStack) Format(s fmt.State, verb rune) {
120+
switch verb {
121+
case 'v':
122+
if s.Flag('+') {
123+
io.WriteString(s, w.Error())
124+
w.stack.Format(s, verb)
125+
return
126+
}
127+
fallthrough
128+
case 's':
129+
io.WriteString(s, w.Error())
130+
}
131+
}
132+
134133
type cause struct {
135134
cause error
136135
msg string

stack.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ func (st StackTrace) Format(s fmt.State, verb rune) {
100100
// stack represents a stack of program counters.
101101
type stack []uintptr
102102

103+
func (s *stack) Format(st fmt.State, verb rune) {
104+
switch verb {
105+
case 'v':
106+
switch {
107+
case st.Flag('+'):
108+
for _, pc := range *s {
109+
f := Frame(pc)
110+
fmt.Fprintf(st, "\n%+v", f)
111+
}
112+
}
113+
}
114+
}
115+
103116
func (s *stack) StackTrace() StackTrace {
104117
f := make([]Frame, len(*s))
105118
for i := 0; i < len(f); i++ {

0 commit comments

Comments
 (0)