Hacker News new | ask | show | jobs
by rwiggins 381 days ago
> how clear and useful it is. Perhaps, but do you really need all that?

Do I need clear and useful things? Maybe not. Would I like to have them anyway? Yes.

Years ago, I configured a Java project's logging framework to automatically exclude all the "uninteresting" frames in stack traces. It was beautiful. Every stack trace showed just the path taken through our application. And we could see the stack of "caused-by" exceptions, and common frames (across exceptions) were automatically cut out, too.

Granted, I'm pretty sure logback's complexity is anathema to Go. But my goodness, it had some nice features...

And then you just throw the stack trace in IntelliJ's "analyze stacktrace" box and you get clickable links to each line in every relevant file... I can dream.

> the wrapping is very greppable when done well

Yeah, that's my other problem with it. _When done well._ Every time I write an `if err != nil {}` block, I need to decide whether to return the error as is (`return err`) or decorate it with further context (`return fmt.Errorf("stuff broke: %w", err)`). (Or use `%v` if I don't want to wrap. Yet another little nuance I find myself needing to explain to junior devs over and over. And don't get me started about putting that in the `fmt` package.)

So anyway, I've seen monstrosities of errors where there were 6+ "statement: statement: statement: statement: statement: final error" that felt like a dark comedy. I've also seen very high-level errors where I dearly wished for some intermediate context, but instead just had "failed to do a thing: EOF".

That all being said, stack traces are really expensive. So, you end up with some "fun" optimizations: https://stackoverflow.com/questions/58696093/when-does-jvm-s...

1 comments

> _When done well._ Every time I write an `if err != nil {}` block, I need to decide whether to return the error as is (`return err`) or decorate it with further context (`return fmt.Errorf("stuff broke: %w", err)`)

Easy. Always wrap. Wrap with what you were doing when the error occurred.

> I'm pretty sure logback's complexity is anathema to Go. But my goodness, it had some nice features... And then you just throw the stack trace in IntelliJ's "analyze stacktrace" box and you get clickable links to each line in every relevant file... I can dream.

Yeah, despite the proliferation of IDEs for Go in recent years, Go has traditionally been pretty anti- big-iron IDE.

> Easy. Always wrap. Wrap with what you were doing when the error occurred.

Then we're back to having stack frames for framework and runtime code in our error traces.

In my experience doing this, it does not. The wrapping is all yours to write—frameworks and the standard library don’t use it. Their errors would appear as “leaf” errors decorated by the wrapping you, as a team, have added.
People who write frameworks and even the standard library are still Go programmers. And all major projects have their own internal libraries and frameworks. So any Go programmer has to learn when it's better to wrap an error, and when it's better to bubble it up as-is.

Or perhaps the people who wrote the Go standard library don't follow the ideal Go best practices?