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

Commit

Permalink
Make errors.stack comparable (#30)
Browse files Browse the repository at this point in the history
Fixed #29

errors.New, etc values are not expected to be compared by value but
the change in errors#27 made them incomparable. Assert that various
kinds of errors have a functional equality operator, even if the
result of that equality is always false.
  • Loading branch information
davecheney committed May 24, 2016
1 parent abe54b4 commit e8c2198
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
19 changes: 10 additions & 9 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ import (
// stack represents a stack of programm counters.
type stack []uintptr

func (s stack) Stack() []uintptr { return s }
func (s *stack) Stack() []uintptr { return *s }

func (s stack) Location() (string, int) {
return location(s[0] - 1)
func (s *stack) Location() (string, int) {
return location((*s)[0] - 1)
}

// New returns an error that formats as the given text.
func New(text string) error {
return struct {
error
stack
*stack
}{
errors.New(text),
callers(),
Expand All @@ -95,7 +95,7 @@ func (c cause) Message() string { return c.message }
func Errorf(format string, args ...interface{}) error {
return struct {
error
stack
*stack
}{
fmt.Errorf(format, args...),
callers(),
Expand All @@ -120,10 +120,10 @@ func Wrapf(cause error, format string, args ...interface{}) error {
return wrap(cause, fmt.Sprintf(format, args...), callers())
}

func wrap(err error, msg string, st stack) error {
func wrap(err error, msg string, st *stack) error {
return struct {
cause
stack
*stack
}{
cause{
cause: err,
Expand Down Expand Up @@ -198,11 +198,12 @@ func Fprint(w io.Writer, err error) {
}
}

func callers() stack {
func callers() *stack {
const depth = 32
var pcs [depth]uintptr
n := runtime.Callers(3, pcs[:])
return pcs[0:n]
var st stack = pcs[0:n]
return &st
}

// location returns the source file and line matching pc.
Expand Down
21 changes: 21 additions & 0 deletions errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,24 @@ func TestStack(t *testing.T) {
}
}
}

// errors.New, etc values are not expected to be compared by value
// but the change in errors#27 made them incomparable. Assert that
// various kinds of errors have a functional equality operator, even
// if the result of that equality is always false.
func TestErrorEquality(t *testing.T) {
tests := []struct {
err1, err2 error
}{
{io.EOF, io.EOF},
{io.EOF, nil},
{io.EOF, errors.New("EOF")},
{io.EOF, New("EOF")},
{New("EOF"), New("EOF")},
{New("EOF"), Errorf("EOF")},
{New("EOF"), Wrap(io.EOF, "EOF")},
}
for _, tt := range tests {
_ = tt.err1 == tt.err2 // mustn't panic
}
}

0 comments on commit e8c2198

Please sign in to comment.