From 2f6f835532243c1cc881c08dbdbaf4bbb593cdb9 Mon Sep 17 00:00:00 2001 From: James Bowes Date: Wed, 21 Jul 2021 18:18:40 -0300 Subject: [PATCH 1/2] temp --- go.mod | 5 ++++- go.sum | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 6cef3d0..a4aa145 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/jbowes/vice go 1.12 -require golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 +require ( + github.com/pkg/errors v0.9.1 + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 +) diff --git a/go.sum b/go.sum index 3ab73ea..e5210ed 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 1a98823bbe6092a77f57dd9f8349751703a4517a Mon Sep 17 00:00:00 2001 From: James Bowes Date: Wed, 21 Jul 2021 20:16:16 -0300 Subject: [PATCH 2/2] Implement frame retrieval and printing locally Reimplement the xerrors style of frame printing with a local pc. This will make it easier for future changes to bring compatibility with other error ecosystems. --- skip/error.go | 21 +++++---------------- skip/frame.go | 26 ++++++++++++++++++++++++++ skip/xerrors.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 skip/frame.go create mode 100644 skip/xerrors.go diff --git a/skip/error.go b/skip/error.go index 61eb4a4..4209094 100644 --- a/skip/error.go +++ b/skip/error.go @@ -1,10 +1,6 @@ package skip -import ( - "fmt" - - "golang.org/x/xerrors" -) +import "fmt" // New returns an error that formats as the given text, and implements the // behaviour described by the given Vice. The argument skip is the number of @@ -97,7 +93,7 @@ func Sealf(err error, v Vice, skip uint, format string, a ...interface{}) error } func sealed(serr *sealError, v Vice, skip uint) error { - serr.frame = xerrors.Caller(int(2 + skip)) + serr.frame = caller(int(2 + skip)) switch v { case Timeout: return &timeoutSeal{*serr} @@ -129,7 +125,7 @@ func sealed(serr *sealError, v Vice, skip uint) error { } func wrapped(werr *wrapError, v Vice, skip uint) error { - werr.frame = xerrors.Caller(int(2 + skip)) + werr.frame = caller(int(2 + skip)) switch v { case Timeout: return &timeoutWrap{*werr} @@ -163,17 +159,10 @@ func wrapped(werr *wrapError, v Vice, skip uint) error { type sealError struct { msg string err error - frame xerrors.Frame + frame frame } -func (e *sealError) Error() string { return fmt.Sprint(e) } -func (e *sealError) Format(s fmt.State, v rune) { xerrors.FormatError(e, s, v) } - -func (e *sealError) FormatError(p xerrors.Printer) (next error) { - p.Print(e.msg) - e.frame.Format(p) - return e.err -} +func (e *sealError) Error() string { return fmt.Sprint(e) } type wrapError struct { sealError diff --git a/skip/frame.go b/skip/frame.go new file mode 100644 index 0000000..1f96125 --- /dev/null +++ b/skip/frame.go @@ -0,0 +1,26 @@ +// frame reimplements stack frame handling in a way that is compatible with +// multiple error ecosystems. + +package skip + +import "runtime" + +type frame [3]uintptr + +func caller(skip int) frame { + var f frame + runtime.Callers(skip+1, f[:]) + return f +} + +func (f frame) detail() (string, string, int) { + frs := runtime.CallersFrames(f[:]) + + if _, ok := frs.Next(); ok { + if fr, ok := frs.Next(); ok { + return fr.Function, fr.File, fr.Line + } + } + + return "", "", 0 +} diff --git a/skip/xerrors.go b/skip/xerrors.go new file mode 100644 index 0000000..b5b4fdb --- /dev/null +++ b/skip/xerrors.go @@ -0,0 +1,34 @@ +// This file holds xerrors specific logic. xerrors was meant to be the +// behaviour that would land in the standard library in go 1.13. Not all +// of it did, but this still remains the default for vice. Still, it is kept +// in its own file to make it easier to remove or put behind a build tag. + +package skip + +import ( + "fmt" + + "golang.org/x/xerrors" +) + +func (e *sealError) Format(s fmt.State, v rune) { xerrors.FormatError(e, s, v) } + +func (e *sealError) FormatError(p xerrors.Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +func (f frame) Format(p xerrors.Printer) { + if !p.Detail() { + return + } + + fn, file, line := f.detail() + if fn != "" { + p.Printf("%s\n ", fn) + } + if file != "" { + p.Printf("%s:%d\n", file, line) + } +}