logoalt Hacker News

teeraylast Tuesday at 5:44 PM3 repliesview on HN

It's funny to me when people see screenfuls of stack traces and remark how clear and useful it is. Perhaps, but do you really need all that? At what cost to your logs? I'd much rather have a one-liner wrapped error that cuts through all the framework and runtime noise. Yes, I can trace just as effectively (usually better)--the wrapping is very greppable when done well. No, in over a decade of writing Go full time, I have never cared about a runtime function or the other usual verbose garbage in my call stack.


Replies

rwigginslast Tuesday at 10:57 PM

> 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...

show 1 reply
jitllast Wednesday at 12:42 AM

Whenever I get an error in NodeJS without a stack trace I am pretty pissed off about it. When my program is failing for some reason I really want to know where it came from, and the stack is hugely helpful in narrowing down the possibility space.

tsimionesculast Wednesday at 11:04 AM

I'm not arguing that stack frames are as good as manually written error traces can be - they're clearly not. I am simply amazed that people include "generate error traces" as a form of "handling" an error.

The argument for explicit error values is often something like "it encourages people to actually handle their errors, rather than ignoring them". And on the face of it, this has some merit: we've all seen code that assumes an HTTP request can't fail, and now a small timeout crashes the entire backup procedure or whatever.

But if "handle the error" simply means "decorate it with a trace and return it", then exceptions already do this, then you're really admitting that there is no fundamental difference from a exception, because this is exactly what exceptions do, all on their own. Sure, they produce less useful traces, but that's usually a tiny difference. After all, the argument wasn't "you'll get better stack traces than exceptions give you", it was "people will be more careful to handle errors".

This is also relevant, because if the goal is to get better error traces, that can also be done with exceptions, with just some small improvements to syntax and semantics (e.g. add syntax for decorating a call site with user supplied context that will get included in any exception bubbled from it; add support in an exception to only print non-library stack frames, add support in the language to declare certain variables as "important" and have them auto-included in stack traces - many ideas).

show 1 reply