Create a virtual stack trace by merging multiple stack traces#13
Create a virtual stack trace by merging multiple stack traces#13
Conversation
Codecov Report
@@ Coverage Diff @@
## master #13 +/- ##
==========================================
+ Coverage 95% 95.54% +0.54%
==========================================
Files 5 5
Lines 140 157 +17
==========================================
+ Hits 133 150 +17
Misses 4 4
Partials 3 3
Continue to review full report at Codecov.
|
| assert.Equal(t, []string{ | ||
| "errFunc1", | ||
| "errFunc2", | ||
| "errFunc3Goroutine.func1", |
There was a problem hiding this comment.
Even when the error is passed between goroutines, a virtual stack trace contains all information.
| f.File = trimGOPATH(fpc.Name(), file) | ||
| f.Line = int64(line) | ||
|
|
||
| if strings.HasPrefix(f.File, "runtime/") { |
There was a problem hiding this comment.
Ignores runtime functions.
| assert.Equal(t, "pkg/sub/file.go", trimGOPATH(funcName, file)) | ||
| } | ||
|
|
||
| func TestMergeStackTraces(t *testing.T) { |
There was a problem hiding this comment.
Here is the strategy for merging multiple stacks.
| }) | ||
| } | ||
|
|
||
| func TestReduceStackTraces(t *testing.T) { |
There was a problem hiding this comment.
var origin = New("test")
func f1() error {
return Wrap(origin)
}
func f2() error {
return Wrap(f1())
}
func f3() chan error {
c := make(chan error)
go func() {
c <- Wrap(f2())
}()
return c
}
func main() {
// init
// f1
// f2
// f3.func1
// main
Wrap(<-f3())
}
stack.go
Outdated
| } | ||
|
|
||
| func (f Frame) hash() string { | ||
| return fmt.Sprintf("%s:%s:%d", f.Func, f.File, f.Line) |
There was a problem hiding this comment.
I feel that calculating hash string is unnecessary.
I guess you should define equal() method and comparing each attribute of this struct.
There was a problem hiding this comment.
Good catch. Didn't even need to customize equal at all...
Currently github.com/pkg/errors.Wrap/Wrapf functions overwrite already attached stack trace. From a UX/DX point of view one would like to add stack trace to an error if none is attached yet. There are several open issues discussing the problem in the original repo: pkg/errors#75 pkg/errors#144 pkg/errors#158 At the moment there is no solution provided, but it looks like the author is willing to make some changes. Until then this commit adds custom Wrap/Wrapf functions which implement this desired behaviour. Other than that, they behave the same way. There is also a pending PR in the original repo: pkg/errors#122 It worths mentioning that there are alternative solutions, like merging stack traces: srvc/fail#13 After examining the solution it seems that it's probably too complicated and unnecessary for most cases. It's also unlikely that the original errors package will implement this behaviour, so for now we stick to the most expected behaviour.
Why
pkg/errors#75
However, this data structure makes it difficult to grasp the flow, and in most cases, it's not compatible with error reporting services.
What
Instead of retaining all stack traces, it creates a virtual stack trace.
It retrives stack trace on every wrap just as pkg/errors does and merges that with the underlying stack trace of the given error.