Skip to content

Commit 1f90d08

Browse files
committed
fmt: make type of fmt.Errorf the same as that of errors.New
This applies only for cases where %w is not used. The purpose of this change is to reduce test failures where tests depend on these two being the same type, as they previously were. Change-Id: I2dd28b93fe1d59f3cfbb4eb0875d1fb8ee699746 Reviewed-on: https://go-review.googlesource.com/c/go/+/167402 Run-TryBot: Marcel van Lohuizen <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Damien Neil <[email protected]>
1 parent 8bf18b5 commit 1f90d08

File tree

5 files changed

+48
-7
lines changed

5 files changed

+48
-7
lines changed

src/errors/errors.go

+18-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
// Package errors implements functions to manipulate errors.
66
package errors
77

8-
import "runtime"
8+
import (
9+
"internal/errinternal"
10+
"runtime"
11+
)
912

1013
// New returns an error that formats as the given text.
1114
//
@@ -15,21 +18,33 @@ func New(text string) error {
1518
// Inline call to errors.Callers to improve performance.
1619
var s Frame
1720
runtime.Callers(2, s.frames[:])
18-
return &errorString{text, s}
21+
return &errorString{text, nil, s}
22+
}
23+
24+
func init() {
25+
errinternal.NewError = func(text string, err error) error {
26+
var s Frame
27+
runtime.Callers(3, s.frames[:])
28+
return &errorString{text, err, s}
29+
}
1930
}
2031

2132
// errorString is a trivial implementation of error.
2233
type errorString struct {
2334
s string
35+
err error
2436
frame Frame
2537
}
2638

2739
func (e *errorString) Error() string {
40+
if e.err != nil {
41+
return e.s + ": " + e.err.Error()
42+
}
2843
return e.s
2944
}
3045

3146
func (e *errorString) FormatError(p Printer) (next error) {
3247
p.Print(e.s)
3348
e.frame.Format(p)
34-
return nil
49+
return e.err
3550
}

src/fmt/errors.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package fmt
66

77
import (
88
"errors"
9+
"internal/errinternal"
910
"strings"
1011
)
1112

@@ -21,7 +22,7 @@ import (
2122
func Errorf(format string, a ...interface{}) error {
2223
err, wrap := lastError(format, a)
2324
if err == nil {
24-
return &noWrapError{Sprintf(format, a...), nil, errors.Caller(1)}
25+
return errinternal.NewError(Sprintf(format, a...), nil)
2526
}
2627

2728
// TODO: this is not entirely correct. The error value could be
@@ -33,7 +34,7 @@ func Errorf(format string, a ...interface{}) error {
3334
if wrap {
3435
return &wrapError{msg, err, errors.Caller(1)}
3536
}
36-
return &noWrapError{msg, err, errors.Caller(1)}
37+
return errinternal.NewError(msg, err)
3738
}
3839

3940
func lastError(format string, a []interface{}) (err error, wrap bool) {

src/fmt/errors_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,21 @@ func TestErrorFormatter(t *testing.T) {
378378
}
379379
}
380380

381+
func TestSameType(t *testing.T) {
382+
err0 := errors.New("inner")
383+
want := fmt.Sprintf("%T", err0)
384+
385+
err := fmt.Errorf("foo: %v", err0)
386+
if got := fmt.Sprintf("%T", err); got != want {
387+
t.Errorf("got %v; want %v", got, want)
388+
}
389+
390+
err = fmt.Errorf("foo %s", "bar")
391+
if got := fmt.Sprintf("%T", err); got != want {
392+
t.Errorf("got %v; want %v", got, want)
393+
}
394+
}
395+
381396
var _ errors.Formatter = wrapped{}
382397

383398
type wrapped struct {

src/go/build/deps_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import (
3434
//
3535
var pkgDeps = map[string][]string{
3636
// L0 is the lowest level, core, nearly unavoidable packages.
37-
"errors": {"runtime", "internal/reflectlite"},
37+
"errors": {"runtime", "internal/errinternal", "internal/reflectlite"},
3838
"io": {"errors", "sync", "sync/atomic"},
3939
"runtime": {"unsafe", "runtime/internal/atomic", "runtime/internal/sys", "runtime/internal/math", "internal/cpu", "internal/bytealg"},
4040
"runtime/internal/sys": {},
@@ -46,6 +46,7 @@ var pkgDeps = map[string][]string{
4646
"unsafe": {},
4747
"internal/cpu": {},
4848
"internal/bytealg": {"unsafe", "internal/cpu"},
49+
"internal/errinternal": {},
4950
"internal/reflectlite": {"runtime", "unsafe"},
5051

5152
"L0": {
@@ -183,7 +184,7 @@ var pkgDeps = map[string][]string{
183184
},
184185

185186
// Formatted I/O: few dependencies (L1) but we must add reflect and internal/fmtsort.
186-
"fmt": {"L1", "bytes", "strings", "os", "reflect", "internal/fmtsort"},
187+
"fmt": {"L1", "bytes", "strings", "os", "reflect", "internal/errinternal", "internal/fmtsort"},
187188
"log": {"L1", "os", "fmt", "time"},
188189

189190
// Packages used by testing must be low-level (L2+fmt).
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright 2019 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package errinternal
6+
7+
// NewError creates a new error as created by errors.New, but with one
8+
// additional stack frame depth.
9+
var NewError func(msg string, err error) error

0 commit comments

Comments
 (0)