added godoc

This commit is contained in:
Dave Cheney 2016-04-22 19:10:04 +09:00
parent e41b26de11
commit a7f2be0bfe
3 changed files with 41 additions and 11 deletions

View File

@ -6,23 +6,41 @@ import (
"io" "io"
"os" "os"
"runtime" "runtime"
"strings"
) )
type loc uintptr
func (l loc) Location() (string, int) {
pc := uintptr(l)
fn := runtime.FuncForPC(pc)
if fn == nil {
return "unknown", 0
}
_, prefix, _, _ := runtime.Caller(0)
file, line := fn.FileLine(pc)
if i := strings.LastIndex(prefix, "github.com/pkg/errors"); i > 0 {
file = file[i:]
}
return file, line
}
// New returns an error that formats as the given text. // New returns an error that formats as the given text.
func New(text string) error { func New(text string) error {
return struct { return struct {
error error
pc uintptr loc
}{ }{
fmt.Errorf(text), fmt.Errorf(text),
pc(), loc(pc()),
} }
} }
type e struct { type e struct {
cause error cause error
message string message string
pc uintptr loc
} }
func (e *e) Error() string { func (e *e) Error() string {
@ -42,7 +60,7 @@ func Wrap(cause error, message string) error {
return &e{ return &e{
cause: cause, cause: cause,
message: message, message: message,
pc: pc(), loc: loc(pc()),
} }
} }
@ -77,6 +95,15 @@ type locationer interface {
} }
// Print prints the error to Stderr. // Print prints the error to Stderr.
// If the error implements the Causer interface described in Cause
// Print will recurse into the error's cause.
// If the error implements the inteface:
//
// type Location interface {
// Location() (file string, line int)
// }
//
// Print will also print the file and line of the error.
func Print(err error) { func Print(err error) {
Fprint(os.Stderr, err) Fprint(os.Stderr, err)
} }
@ -89,7 +116,7 @@ func Fprint(w io.Writer, err error) {
location, ok := err.(locationer) location, ok := err.(locationer)
if ok { if ok {
file, line := location.Location() file, line := location.Location()
fmt.Fprint(w, "%s:%d: ", file, line) fmt.Fprintf(w, "%s:%d: ", file, line)
} }
switch err := err.(type) { switch err := err.(type) {
case *e: case *e:

View File

@ -124,10 +124,10 @@ func TestFprint(t *testing.T) {
want: "error\n", want: "error\n",
}, { }, {
err: Wrap(x, "message"), err: Wrap(x, "message"),
want: "message\nerror\n", want: "github.com/pkg/errors/errors_test.go:126: message\nerror\n",
}, { }, {
err: Wrap(Wrap(x, "message"), "another message"), err: Wrap(Wrap(x, "message"), "another message"),
want: "another message\nmessage\nerror\n", want: "github.com/pkg/errors/errors_test.go:129: another message\ngithub.com/pkg/errors/errors_test.go:129: message\nerror\n",
}} }}
for i, tt := range tests { for i, tt := range tests {

View File

@ -23,7 +23,10 @@ func ExampleWrap() {
} }
func fn() error { func fn() error {
return errors.Wrap(errors.Wrap(errors.Wrap(errors.New("error"), "inner"), "middle"), "outer") e1 := errors.New("error")
e2 := errors.Wrap(e1, "inner")
e3 := errors.Wrap(e2, "middle")
return errors.Wrap(e3, "outer")
} }
func ExampleCause() { func ExampleCause() {
@ -39,8 +42,8 @@ func ExampleFprint() {
err := fn() err := fn()
errors.Fprint(os.Stdout, err) errors.Fprint(os.Stdout, err)
// Output: outer // Output: github.com/pkg/errors/example_test.go:29: outer
// middle // github.com/pkg/errors/example_test.go:28: middle
// inner // github.com/pkg/errors/example_test.go:27: inner
// error // error
} }