aboutsummaryrefslogtreecommitdiff
path: root/src/errors
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2019-05-13 14:51:55 -0700
committerDamien Neil <dneil@google.com>2019-05-15 19:53:15 +0000
commit3e2c522d5c712fa2b1d18a101272abefc7dcb074 (patch)
treeff30ae55319bd82eb832829a2c65c252d3969abb /src/errors
parent599ec7720fefdb60344bb4a9dab481ed302aa473 (diff)
downloadgo-3e2c522d5c712fa2b1d18a101272abefc7dcb074.tar.xz
errors, fmt: revert rejected changes for Go 1.13
Reverts the following changes: https://go.googlesource.com/go/+/1f90d081391d4f5911960fd28d81d7ea5e554a8f https://go.googlesource.com/go/+/8bf18b56a47a98b9dd2fa03beb358312237a8c76 https://go.googlesource.com/go/+/5402854c3557f87fa2741a52ffc15dfb1ef333cc https://go.googlesource.com/go/+/37f84817247d3b8e687a701ccb0d6bc7ffe3cb78 https://go.googlesource.com/go/+/6be6f114e0d483a233101a67c9644cd72bd3ae7a Partially reverts the followinng change, removing the errors.Opaque function and the errors.Wrapper type definition: https://go.googlesource.com/go/+/62f5e8156ef56fa61e6af56f4ccc633bde1a9120 Updates documentation referencing the Wrapper type. Change-Id: Ia622883e39cafb06809853e3fd90b21441124534 Reviewed-on: https://go-review.googlesource.com/c/go/+/176997 Run-TryBot: Damien Neil <dneil@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Diffstat (limited to 'src/errors')
-rw-r--r--src/errors/errors.go34
-rw-r--r--src/errors/format.go34
-rw-r--r--src/errors/frame.go47
-rw-r--r--src/errors/frame_test.go66
-rw-r--r--src/errors/wrap.go29
-rw-r--r--src/errors/wrap_test.go61
6 files changed, 5 insertions, 266 deletions
diff --git a/src/errors/errors.go b/src/errors/errors.go
index 51175b13c8..b8a46921be 100644
--- a/src/errors/errors.go
+++ b/src/errors/errors.go
@@ -5,46 +5,16 @@
// Package errors implements functions to manipulate errors.
package errors
-import (
- "internal/errinternal"
- "runtime"
-)
-
// New returns an error that formats as the given text.
-//
-// The returned error contains a Frame set to the caller's location and
-// implements Formatter to show this information when printed with details.
func New(text string) error {
- // Inline call to errors.Callers to improve performance.
- var s Frame
- runtime.Callers(2, s.frames[:])
- return &errorString{text, nil, s}
-}
-
-func init() {
- errinternal.NewError = func(text string, err error) error {
- var s Frame
- runtime.Callers(3, s.frames[:])
- return &errorString{text, err, s}
- }
+ return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
- s string
- err error
- frame Frame
+ s string
}
func (e *errorString) Error() string {
- if e.err != nil {
- return e.s + ": " + e.err.Error()
- }
return e.s
}
-
-func (e *errorString) FormatError(p Printer) (next error) {
- p.Print(e.s)
- e.frame.Format(p)
- return e.err
-}
diff --git a/src/errors/format.go b/src/errors/format.go
deleted file mode 100644
index 12deed3cf7..0000000000
--- a/src/errors/format.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package errors
-
-// A Formatter formats error messages.
-type Formatter interface {
- error
-
- // FormatError prints the receiver's first error and returns the next error in
- // the error chain, if any.
- FormatError(p Printer) (next error)
-}
-
-// A Printer formats error messages.
-//
-// The most common implementation of Printer is the one provided by package fmt
-// during Printf. Localization packages such as golang.org/x/text/message
-// typically provide their own implementations.
-type Printer interface {
- // Print appends args to the message output.
- Print(args ...interface{})
-
- // Printf writes a formatted string.
- Printf(format string, args ...interface{})
-
- // Detail reports whether error detail is requested.
- // After the first call to Detail, all text written to the Printer
- // is formatted as additional detail, or ignored when
- // detail has not been requested.
- // If Detail returns false, the caller can avoid printing the detail at all.
- Detail() bool
-}
diff --git a/src/errors/frame.go b/src/errors/frame.go
deleted file mode 100644
index 487092fa89..0000000000
--- a/src/errors/frame.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package errors
-
-import (
- "runtime"
-)
-
-// A Frame contains part of a call stack.
-type Frame struct {
- frames [1]uintptr
-}
-
-// Caller returns a Frame that describes a frame on the caller's stack.
-// The argument skip is the number of frames to skip over.
-// Caller(0) returns the frame for the caller of Caller.
-func Caller(skip int) Frame {
- var s Frame
- runtime.Callers(skip+2, s.frames[:])
- return s
-}
-
-// location reports the file, line, and function of a frame.
-//
-// The returned function may be "" even if file and line are not.
-func (f Frame) location() (function, file string, line int) {
- frames := runtime.CallersFrames(f.frames[:])
- fr, _ := frames.Next()
- return fr.Function, fr.File, fr.Line
-}
-
-// Format prints the stack as error detail.
-// It should be called from an error's Format implementation,
-// before printing any other error detail.
-func (f Frame) Format(p Printer) {
- if p.Detail() {
- function, file, line := f.location()
- if function != "" {
- p.Printf("%s\n ", function)
- }
- if file != "" {
- p.Printf("%s:%d\n", file, line)
- }
- }
-}
diff --git a/src/errors/frame_test.go b/src/errors/frame_test.go
deleted file mode 100644
index ba08166966..0000000000
--- a/src/errors/frame_test.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package errors_test
-
-import (
- "bytes"
- "errors"
- "fmt"
- "math/big"
- "regexp"
- "strings"
- "testing"
-)
-
-func TestFrame(t *testing.T) {
-
- // Extra line
- got := fmt.Sprintf("%+v", errors.New("Test"))
- got = got[strings.Index(got, "Test"):]
- const want = "^Test:" +
- "\n errors_test.TestFrame" +
- "\n .*/errors/frame_test.go:20$"
- ok, err := regexp.MatchString(want, got)
- if err != nil {
- t.Fatal(err)
- }
- if !ok {
- t.Errorf("\n got %v;\nwant %v", got, want)
- }
-}
-
-type myType struct{}
-
-func (myType) Format(s fmt.State, v rune) {
- s.Write(bytes.Repeat([]byte("Hi! "), 10))
-}
-
-func BenchmarkNew(b *testing.B) {
- for i := 0; i < b.N; i++ {
- _ = errors.New("new error")
- }
-}
-
-func BenchmarkErrorf(b *testing.B) {
- err := errors.New("foo")
- args := func(a ...interface{}) []interface{} { return a }
- benchCases := []struct {
- name string
- format string
- args []interface{}
- }{
- {"no_format", "msg: %v", args(err)},
- {"with_format", "failed %d times: %v", args(5, err)},
- {"method: mytype", "pi %s %v: %v", args("myfile.go", myType{}, err)},
- {"method: number", "pi %s %d: %v", args("myfile.go", big.NewInt(5), err)},
- }
- for _, bc := range benchCases {
- b.Run(bc.name, func(b *testing.B) {
- for i := 0; i < b.N; i++ {
- _ = fmt.Errorf(bc.format, bc.args...)
- }
- })
- }
-}
diff --git a/src/errors/wrap.go b/src/errors/wrap.go
index b53caa6fc9..62332b1a88 100644
--- a/src/errors/wrap.go
+++ b/src/errors/wrap.go
@@ -8,35 +8,12 @@ import (
"internal/reflectlite"
)
-// A Wrapper provides context around another error.
-type Wrapper interface {
- // Unwrap returns the next error in the error chain.
- // If there is no next error, Unwrap returns nil.
- Unwrap() error
-}
-
-// Opaque returns an error with the same error formatting as err
-// but that does not match err and cannot be unwrapped.
-func Opaque(err error) error {
- return noWrapper{err}
-}
-
-type noWrapper struct {
- error
-}
-
-func (e noWrapper) FormatError(p Printer) (next error) {
- if f, ok := e.error.(Formatter); ok {
- return f.FormatError(p)
- }
- p.Print(e.error)
- return nil
-}
-
// Unwrap returns the result of calling the Unwrap method on err, if err
// implements Wrapper. Otherwise, Unwrap returns nil.
func Unwrap(err error) error {
- u, ok := err.(Wrapper)
+ u, ok := err.(interface {
+ Unwrap() error
+ })
if !ok {
return nil
}
diff --git a/src/errors/wrap_test.go b/src/errors/wrap_test.go
index f8e907cff7..2055316756 100644
--- a/src/errors/wrap_test.go
+++ b/src/errors/wrap_test.go
@@ -5,7 +5,6 @@
package errors_test
import (
- "bytes"
"errors"
"fmt"
"os"
@@ -16,8 +15,6 @@ func TestIs(t *testing.T) {
err1 := errors.New("1")
erra := wrapped{"wrap 2", err1}
errb := wrapped{"wrap 3", erra}
- erro := errors.Opaque(err1)
- errco := wrapped{"opaque", erro}
err3 := errors.New("3")
@@ -35,9 +32,6 @@ func TestIs(t *testing.T) {
{err1, err1, true},
{erra, err1, true},
{errb, err1, true},
- {errco, erro, true},
- {errco, err1, false},
- {erro, erro, true},
{err1, err3, false},
{erra, err3, false},
{errb, err3, false},
@@ -45,8 +39,6 @@ func TestIs(t *testing.T) {
{poser, err3, true},
{poser, erra, false},
{poser, errb, false},
- {poser, erro, false},
- {poser, errco, false},
{errorUncomparable{}, errorUncomparable{}, true},
{errorUncomparable{}, &errorUncomparable{}, false},
{&errorUncomparable{}, errorUncomparable{}, true},
@@ -108,10 +100,6 @@ func TestAs(t *testing.T) {
&errP,
true,
}, {
- errors.Opaque(errT),
- &errT,
- false,
- }, {
errorT{},
&errP,
false,
@@ -187,7 +175,6 @@ func TestAsValidation(t *testing.T) {
func TestUnwrap(t *testing.T) {
err1 := errors.New("1")
erra := wrapped{"wrap 2", err1}
- erro := errors.Opaque(err1)
testCases := []struct {
err error
@@ -198,9 +185,6 @@ func TestUnwrap(t *testing.T) {
{err1, nil},
{erra, err1},
{wrapped{"wrap 3", erra}, erra},
-
- {erro, nil},
- {wrapped{"opaque", erro}, erro},
}
for _, tc := range testCases {
if got := errors.Unwrap(tc.err); got != tc.want {
@@ -209,39 +193,6 @@ func TestUnwrap(t *testing.T) {
}
}
-func TestOpaque(t *testing.T) {
- someError := errors.New("some error")
- testCases := []struct {
- err error
- next error
- }{
- {errorT{}, nil},
- {wrapped{"b", nil}, nil},
- {wrapped{"c", someError}, someError},
- }
- for _, tc := range testCases {
- t.Run("", func(t *testing.T) {
- opaque := errors.Opaque(tc.err)
-
- f, ok := opaque.(errors.Formatter)
- if !ok {
- t.Fatal("Opaque error does not implement Formatter")
- }
- var p printer
- next := f.FormatError(&p)
- if next != tc.next {
- t.Errorf("next was %v; want %v", next, tc.next)
- }
- if got, want := p.buf.String(), tc.err.Error(); got != want {
- t.Errorf("error was %q; want %q", got, want)
- }
- if got := errors.Unwrap(opaque); got != nil {
- t.Errorf("Unwrap returned non-nil error (%v)", got)
- }
- })
- }
-}
-
type errorT struct{}
func (errorT) Error() string { return "errorT" }
@@ -255,18 +206,6 @@ func (e wrapped) Error() string { return e.msg }
func (e wrapped) Unwrap() error { return e.err }
-func (e wrapped) FormatError(p errors.Printer) error {
- p.Print(e.msg)
- return e.err
-}
-
-type printer struct {
- errors.Printer
- buf bytes.Buffer
-}
-
-func (p *printer) Print(args ...interface{}) { fmt.Fprint(&p.buf, args...) }
-
type errorUncomparable struct {
f []string
}