Skip to content

Commit d61658b

Browse files
committed
xerrors: redirect to go1.13 primitives for 1.13
For interoperability it is especially important that the Printer type is redirected. Otherwise the FormatError method would not be of the same signature and there would be no interoperability. Some of the more bulky code is now also redirected to use 1.13. Tests are verified to pass for both go1.12 and go1.13. Change-Id: Ia5776252aa4774d900c53661659d9a8b61793015 Reviewed-on: https://go-review.googlesource.com/c/xerrors/+/167577 Run-TryBot: Marcel van Lohuizen <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Damien Neil <[email protected]>
1 parent a5947ff commit d61658b

File tree

6 files changed

+99
-10
lines changed

6 files changed

+99
-10
lines changed

adaptor.go renamed to adaptor_go1_12.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5+
// +build !go1.13
6+
57
package xerrors
68

79
import (

adaptor_go1_13.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2018 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+
// +build go1.13
6+
7+
package xerrors
8+
9+
import (
10+
"errors"
11+
"fmt"
12+
"strconv"
13+
)
14+
15+
// A Frame contains part of a call stack.
16+
type Frame = errors.Frame
17+
18+
// Caller returns a Frame that describes a frame on the caller's stack.
19+
// The argument skip is the number of frames to skip over.
20+
// Caller(0) returns the frame for the caller of Caller.
21+
var Caller func(skip int) Frame = errors.Caller
22+
23+
// FormatError calls the FormatError method of f with an errors.Printer
24+
// configured according to s and verb, and writes the result to s.
25+
func FormatError(f Formatter, s fmt.State, verb rune) {
26+
// Assuming this function is only called from the Format method, and given
27+
// that FormatError takes precedence over Format, it cannot be called from
28+
// any package that supports errors.Formatter. It is therefore safe to
29+
// disregard that State may be a specific printer implementation and use one
30+
// of our choice instead.
31+
32+
width, okW := s.Width()
33+
prec, okP := s.Precision()
34+
35+
// Construct format string from State s.
36+
format := []byte{'%'}
37+
if s.Flag('-') {
38+
format = append(format, '-')
39+
}
40+
if s.Flag('+') {
41+
format = append(format, '+')
42+
}
43+
if s.Flag(' ') {
44+
format = append(format, ' ')
45+
}
46+
if okW {
47+
format = strconv.AppendInt(format, int64(width), 10)
48+
}
49+
if okP {
50+
format = append(format, '.')
51+
format = strconv.AppendInt(format, int64(prec), 10)
52+
}
53+
format = append(format, string(verb)...)
54+
fmt.Fprintf(s, string(format), f)
55+
}

fmt_test.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package xerrors_test
77
import (
88
"fmt"
99
"io"
10-
"os"
1110
"path"
1211
"reflect"
1312
"regexp"
@@ -91,7 +90,7 @@ func TestErrorFormatter(t *testing.T) {
9190
nonascii = &wrapped{"café", nil}
9291
newline = &wrapped{"msg with\nnewline",
9392
&wrapped{"and another\none", nil}}
94-
fallback = &wrapped{"fallback", os.ErrNotExist}
93+
fallback = &wrapped{"fallback", xerrors.New("file does not exist")}
9594
oldAndNew = &wrapped{"new style", formatError("old style")}
9695
framed = &withFrameAndMore{
9796
frame: xerrors.Caller(0),
@@ -106,6 +105,13 @@ func TestErrorFormatter(t *testing.T) {
106105
want string
107106
regexp bool
108107
}{{
108+
err: xerrors.New("foo"),
109+
fmt: "%+v",
110+
want: "foo:" +
111+
"\n golang.org/x/xerrors_test.TestErrorFormatter" +
112+
"\n .+/golang.org/x/xerrors/fmt_test.go:1\\d\\d",
113+
regexp: true,
114+
}, {
109115
err: simple,
110116
fmt: "%s",
111117
want: "simple",
@@ -156,7 +162,7 @@ func TestErrorFormatter(t *testing.T) {
156162
fmt: "%+v",
157163
want: "something:" +
158164
"\n golang.org/x/xerrors_test.TestErrorFormatter" +
159-
"\n .+/fmt_test.go:97" +
165+
"\n .+/fmt_test.go:9\\d" +
160166
"\n something more",
161167
regexp: true,
162168
}, {
@@ -173,7 +179,10 @@ func TestErrorFormatter(t *testing.T) {
173179
// Note: no colon after the last error, as there are no details.
174180
want: "fallback:" +
175181
"\n somefile.go:123" +
176-
"\n - file does not exist",
182+
"\n - file does not exist:" +
183+
"\n golang.org/x/xerrors_test.TestErrorFormatter" +
184+
"\n .+/golang.org/x/xerrors/fmt_test.go:9\\d",
185+
regexp: true,
177186
}, {
178187
err: opaque,
179188
fmt: "%s",
@@ -281,12 +290,12 @@ func TestErrorFormatter(t *testing.T) {
281290
err: simple,
282291
fmt: "%T",
283292
want: "*xerrors_test.wrapped",
284-
}, {
285-
err: simple,
286-
fmt: "%🤪",
287-
want: "%!🤪(*xerrors_test.wrapped)",
288-
// For 1.13:
289-
// want: "%!🤪(*xerrors_test.wrapped=&{simple <nil>})",
293+
// }, {
294+
// // The behavior for this case is different between go1.12 and go1.13.
295+
// err: simple,
296+
// fmt: "%🤪",
297+
// want: "%!🤪(*xerrors_test.wrapped=&{simple <nil>})", // go1.12
298+
// want: "&{%!🤪(string=simple) <nil>}", // go1.13
290299
}, {
291300
err: formatError("use fmt.Formatter"),
292301
fmt: "%#v",

format.go renamed to format_go1_12.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5+
// +build !go1.13
6+
57
package xerrors
68

79
// A Formatter formats error messages.

format_go1_13.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2018 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+
// +build go1.13
6+
7+
package xerrors
8+
9+
import "errors"
10+
11+
// A Formatter formats error messages.
12+
type Formatter = errors.Formatter
13+
14+
// A Printer formats error messages.
15+
//
16+
// The most common implementation of Printer is the one provided by package fmt
17+
// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message
18+
// typically provide their own implementations.
19+
type Printer = errors.Printer

frame.go renamed to frame_go1_12.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5+
// +build !go1.13
6+
57
package xerrors
68

79
import (

0 commit comments

Comments
 (0)