diff --git a/README.md b/README.md index 0739c87..dc0c2fe 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,83 @@ The exported package is `errors`, basic usage: import "github.com/coditory/go-errors" func main() { - // TBD + err := foo() + fmt.Printf("\n>>> Format %%s:\n%s", err) + fmt.Printf("\n>>> Format %%v:\n%v", err) + fmt.Printf("\n>>> Format %%+v:\n%+v", err) + fmt.Printf("\n>>> Format %%#v:\n%#v", err) } + +func foo() error { + err := bar() + return errors.Wrap(err, "foo failed") +} + +func bar() error { + return errors.New("bar failed") +} +``` + +Output for `go run ./samples` + +``` +>>> Format %s: +foo failed + +>>> Format %v: +foo failed + main.foo:19 + main.main:10 + runtime.main:250 + runtime.goexit:1598 +caused by: bar failed + main.bar:23 + main.foo:18 + main.main:10 + runtime.main:250 + runtime.goexit:1598 + +>>> Format %+v: +foo failed + ./samples.go:19 + main.foo + ./samples.go:10 + main.main + /runtime/proc.go:250 + runtime.main + /runtime/asm_amd64.s:1598 + runtime.goexit +caused by: bar failed + ./samples.go:23 + main.bar + ./samples.go:18 + main.foo + ./samples.go:10 + main.main + /runtime/proc.go:250 + runtime.main + /runtime/asm_amd64.s:1598 + runtime.goexit + +>>> Format %#v: +foo failed + /samples/samples.go:19 + main.foo + /samples/samples.go:10 + main.main + /runtime/proc.go:250 + runtime.main + /runtime/asm_amd64.s:1598 + runtime.goexit +caused by: bar failed + /samples/samples.go:23 + main.bar + /samples/samples.go:18 + main.foo + /Users/mendlik/Development/go/go-errors/samples/samples.go:10 + main.main + /runtime/proc.go:250 + runtime.main + /runtime/asm_amd64.s:1598 + runtime.goexit ``` diff --git a/errors.go b/errors.go index 057e029..eb4fd9e 100644 --- a/errors.go +++ b/errors.go @@ -48,9 +48,6 @@ type Error struct { } func (e *Error) Error() string { - if e.message != "" && e.err != nil { - return fmt.Sprintf("%s: %s", e.message, e.err.Error()) - } if e.message != "" { return e.message } @@ -71,7 +68,7 @@ func (e *Error) StackTrace() StackTrace { func (e *Error) Format(s fmt.State, verb rune) { switch verb { case 'v': - e.formatCauses(s, s.Flag('+')) + e.formatCauses(s) case 's': write(s, e.Error()) case 'q': @@ -79,7 +76,7 @@ func (e *Error) Format(s fmt.State, verb rune) { } } -func (e *Error) formatCauses(s fmt.State, plus bool) { +func (e *Error) formatCauses(s fmt.State) { var err error err = e causes := 0 @@ -99,9 +96,12 @@ func (e *Error) formatCauses(s fmt.State, plus bool) { } for i := 0; i < n; i++ { frame := stacktrace[i] - if plus { + if s.Flag('+') { fmt.Fprintf(s, "\t%s:%d\n", frame, frame) fmt.Fprintf(s, "\t\t%n\n", frame) + } else if s.Flag('#') { + fmt.Fprintf(s, "\t%+s:%d\n", frame, frame) + fmt.Fprintf(s, "\t\t%+n\n", frame) } else { fmt.Fprintf(s, "\t%n:%d\n", frame, frame) } @@ -114,10 +114,6 @@ func (e *Error) formatCauses(s fmt.State, plus bool) { } } } - if werr, ok := err.(*Error); ok { - // deduplicate wrapped error message - err = werr.Unwrap() - } if werr, ok := err.(wrapper); ok { err = werr.Unwrap() } else { @@ -298,7 +294,11 @@ func relName(name string) string { if strings.HasPrefix(BasePath, "**/") { i := strings.Index(name, BasePath[3:]) if i > 0 { - return "./" + name[i+len(BasePath)-2:] + name = name[i+len(BasePath)-2:] + for strings.HasPrefix(name, BasePath[3:]) { + name = name[len(BasePath)-2:] + } + return "./" + name } } else if strings.HasPrefix(name, BasePath) { return name[len(BasePath)+1:] diff --git a/samples/samples.go b/samples/samples.go new file mode 100644 index 0000000..e603cb3 --- /dev/null +++ b/samples/samples.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + + "github.com/coditory/go-errors" +) + +func main() { + err := foo() + fmt.Printf("\n>>> Format %%s:\n%s", err) + fmt.Printf("\n>>> Format %%v:\n%v", err) + fmt.Printf("\n>>> Format %%+v:\n%+v", err) + fmt.Printf("\n>>> Format %%#v:\n%#v", err) +} + +func foo() error { + err := bar() + return errors.Wrap(err, "foo failed") +} + +func bar() error { + return errors.New("bar failed") +} diff --git a/test/common_test.go b/test/common_test.go new file mode 100644 index 0000000..c3103de --- /dev/null +++ b/test/common_test.go @@ -0,0 +1,11 @@ +package errors_test + +import ( + "github.com/coditory/go-errors" +) + +func init() { + errors.BaseModule = "github.com/coditory/go-errors" + errors.BasePath = "**/go-errors" + errors.BaseCachePath = "**/mod/pkg" +} diff --git a/test/errors_test.go b/test/errors_test.go index 1e99028..5b47b88 100644 --- a/test/errors_test.go +++ b/test/errors_test.go @@ -13,33 +13,12 @@ import ( type ErrorsSuite struct { suite.Suite - BackupBasePath string - BackupBaseModule string - BackupBaseCachePath string } func TestErrorsSuite(t *testing.T) { suite.Run(t, new(ErrorsSuite)) } -func (suite *ErrorsSuite) SetupSuite() { - suite.BackupBaseModule = errors.BaseModule - suite.BackupBasePath = errors.BasePath - suite.BackupBaseCachePath = errors.BaseCachePath -} - -func (suite *ErrorsSuite) TearDownSuite() { - errors.BaseModule = suite.BackupBaseModule - errors.BasePath = suite.BackupBasePath - errors.BaseCachePath = suite.BackupBaseCachePath -} - -func (suite *ErrorsSuite) SetupTest() { - errors.BaseModule = "github.com/coditory/go-errors" - errors.BasePath = "**/go-errors" - errors.BaseCachePath = "**/mod/pkg" -} - func (suite *ErrorsSuite) TestNewError() { err := errors.New("foo") suite.Equal("foo", err.Error())