5 ms·
Stack traces are desperately needed to give errors context, and I was very disappointed to see that proposal dropped from Go 1.13. At the same time, I'm hesitan
by jniedrauer 7y ago
Stack traces are desperately needed to give errors context, and I was very disappointed to see that proposal dropped from Go 1.13. At the same time, I'm hesitant to use xerrors in production code because it's likely to change rapidly in the future.
I had a situation recently where a fairly complicated API was returning an HTTP 403 in production. Once the error bubbled down to a level where it was actually logged, all that was left was "403 Forbidden". I spent days echo debugging and could not reproduce the problem. Finally, by chance, I happened on the problem while working on something completely unrelated. With a stack trace, 3 days of work would have taken 5 minutes. Wrapping would not help in this situation unless every single error was wrapped with a unique string, which frankly is ridiculous.
- vbezhenar 7y agoIt's funny how people like to bash long Java stacktraces, while they help immensely in the situations like these. It's obvious from the start where the error is and all those stacks can help you to find out every little detail that lead to the problem.
- weberc2 7y agoI’m only familiar with people bashing long Java stack traces because (1) they are often hilariously long, with stateless web applications dumping tenfold the frames of a crashing webbrowser, (2) they contain some number of abstract factory beans (contributing to the length problem) and (3) they show up far more frequently in user-facing applications than just about any other language. Stack traces are great, gratuitous abstraction, buggy code, and exposing stack traces to users are not great.
- klodolph 7y agoThe stack traces tend to be useful when there is a programming error in your program, and less useful when there is any other type of error. In Go, programming errors usually panic which will print a stack trace by default. But I’ll see Java programs that give me stack traces just because I’ve misconfigured them, or the server is down, or I have a bad network connection, or a file is missing. This is awful UX. Worse, the stack trace might not tell me WHICH file is missing, or WHICH server is down. You only get good UX for errors by manually annotating context in the places in your code where the context is known. (My personal experience is that FAR too many actual Java programs in the wild will give me a stack trace when they should give a short error message.)
- JulianMorrison 7y agoI feel like, in Go, the ideal is to handle the error in situ. If it has to be passed up, it goes the shortest possible distance before reaching code that can handle it. This is a difference from exception-throwing languages and so it changes the importance of a stack trace. You don't need to know where it broke because it broke here. The same approach as in C. You test the result where you made the call.
- jniedrauer 7y agoOn the surface this sounds logical. But going back to the case I dealt with recently, all errors during authentication lead back to an HTTP 403 workflow. Errors themselves can occur a long distance from any sane central place to handle them. Unless you pass the http.ResponseWriter all the way up the stack, the only "in place" handling you could do is to log every error along with a unique string. Is this really the best we can do? if err := frobulate(); err != nil { log.Printf("Error on line 123: %+v", err) return err }
- q3k 7y agoYou example is code smell. When dealing with error handling in Go (and many other languages), you should do one _and only one_ of the following: - if you have enough context to handle the error (eg. retry, or degrade gracefully, or perform whatever other application logic to recover, possibly returning a more friendly error to your caller), do that, possibly logging the source error and do not return it further up the stack directly - you have now healed the error condition, and the application code can continue. - otherwise, return the error, decorating it with extra context if possible. Doing both, ie. logging (which is a case of handling the error) and returning it up the stack leads to extremely chatty and difficult to debug code. Errors are a fact of life, and your path of handling them should be as well engineered as the happy life. That's one of the most important things in writing reliable software. That's also one of the reasons there's no generic stack unwinding/exceptions on Go: it forces you to _think_ about error cases and at least reminds you to handle them gracefully. You might not like this approach of treating programmers this way, but that's one of the cornerstones of Go.
- aikah 7y ago> Stack traces are desperately needed to give errors context, and I was very disappointed to see that proposal dropped from Go 1.13. At the same time, I'm hesitant to use xerrors in production code because it's likely to change rapidly in the future. By the way what's left of all the "Go 2" proposals? "generics" look like they are in limbo and so is the "try/catch" proposal. Has anything been implemented yet?
- weberc2 7y agoPretty sure the try proposal was killed. Generics hasn’t seen much headway to my knowledge. Not sure what’s up with it.
- xienze 7y ago> Generics hasn’t seen much headway to my knowledge. Not sure what’s up with it. They don't want to do generics, they never have.
- ithkuil 7y agoSo you know for sure that consensus around https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md https://go.googlesource.com/proposal/+/master/design/go2draf... is impossible to reach?
- earthboundkid 7y agoI have no inside knowledge, but my guess as an observer is they’re just plugging away at implementation behind the scenes and some descendent of that proposal will be what ships.
- _ph_ 7y agoWhat is preventing you to attach runtime.debug.Stack() to your errors to get the stack traces?
- naikrovek 7y agoStack traces exist in Go today, though...