errors
errors copied to clipboard
if an error somehow wraps itself, Error() recurses forever
I know it's totally my bad to cause this in the first place, but I've somehow made err.Error() recurse forever, which means the err itself is the cause. I haven't tracked it down yet, but detecting if the Error() chain loops might be nice, as I had to use delve and print 200k lines of stacktrace to figure out what was wrong.
https://github.com/pkg/errors/blob/master/errors.go#L228
ooh, that's bad. If you can make a repro so I can turn it into a test that would be much appreciated.
On Fri, Sep 1, 2017 at 9:39 AM, Ryan Hileman [email protected] wrote:
I know it's totally my bad to cause this in the first place, but I've somehow made err.Error() recurse forever, which means the err itself is the cause. I haven't tracked it down yet, but detecting if the Error() chain loops might be nice, as I had to use delve and print 200k lines of stacktrace to figure out what was wrong.
https://github.com/pkg/errors/blob/master/errors.go#L228
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pkg/errors/issues/131, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAcAxPeF54EreBUipOKNROlsD9MpcNlks5sd0Q7gaJpZM4PJieV .
Okay, so this was a different problem than I thought- so not a recursive error- (and totally my fault): a file format parser bug resulted in the next input "frame" being parsed as a recursion of the previous frame. When the very last frame throws io.EOF, it bubbles all the way out (200k stack frames, 200k times errors.Wrap()).
Now withMessage.Error() is quadratic time due to the simple string concat, so deeply nested errors are actually pretty slow as per this gist (which needs to be run locally, not on play.golang.org): https://gist.github.com/lunixbochs/00262cfc53c5096b57274768209f6aa6
I get this output for 20k iterations:
quadratic 511.538ms 100005
linear 2.830926ms 100008
It was taking tens of seconds to print the error message, which is why my stack trace was just miles of withMessage.Error().
Now, I don't think this is real-world case enough to actually fix like this (as a dumb list join is slower for real-world error nesting, like ~20), but if someone in the future ever ends up with this many nested errors.withMessage they will be just as confused as me.
It's also a contrived DoS case.