4 ms·
How is decoding a stack trace easier for Go programs? My experience has been that Go programs simply don't generate stack traces when something goes wrong. Inst
by repolfx 8y ago
How is decoding a stack trace easier for Go programs? My experience has been that Go programs simply don't generate stack traces when something goes wrong. Instead you get some log message with a generic "Something went wrong in subsystem X" type message because the error codes got passed up and abstracted by hand. Exceptions with stack traces are far, far superior to that when it comes to rapidly identifying and fixing faults.
- klodolph 8y agoIn Golang you will typically annotate the error messages with meaningful context as you go up the stack. By comparison, my experience is that often, exceptions only have the stack and one error message, and are missing critical pieces of context. The stack trace will only contain the names of functions, and it will often contain the names of functions that are irrelevant to debugging. A good error message might look like this: Could not travel to Alpha Centauri: warp drive initialization failed: power coupling 397 is offline: temperature out of range (temp = 150°C) A bad stack trace might look like this: DeviceClient::Connect() std::promise::something <anonymous function> DeviceSet::PowerOnAllDevices() <anonymous function> std::etcetera std::etcetera<some_big_thing, more_params, allocator=std::allocator> TravelCommand::Engage() VoiceCommand::RunCommand() Error: temperature out of range (temp = 150°C) Stack traces are useful, but they're a poor substitute for good error messages. There's just too much context missing from raw stack traces (which file, which URL, which device) and too much noise (anonymous functions, higher-order functions, etc.) That, and a stack trace often requires reading the source code to interpret properly. That might not be possible or it might be outside the skill set of the person interpreting the error. Exceptions optimize for the case where the exception bubbles straight up to some handler, but I'd rather not have my errors work that way. It's incredibly common for it to make no sense to bubble an error up without some kind of annotation or additional context.
- pvg 8y agoThis doesn't seen like a particularly fair comparison because bad error messages (if we are to compare them to a bad stack trace) look like this:
- klodolph 8y agoI'm not sure if you're trying to make some kind of joke. An empty string is a bad error message, but you would have to go out of your way to make this happen in Go, you would have to do something obviously wrong like return errors.New("") You have control over whether the error messages are good or bad, you just have to insert the right annotations where the critical pieces of context are known. Stack traces are not like this, you can't really control whether they are good or bad, at least not well. If you want to make your stack traces more informative what do you do? You can't really change them, they just reflect your call graph. Golang optimizes for the case where you get good error messages. Exceptions optimize for the case where you don't care about adding context to the error and just want to bubble it upwards. On the balance of things, I prefer Golang's approach because most of the time, I don't want to see the stack trace.
- pvg 8y agoExceptions in many languages carry messages and exceptions can be nested. There's also nothing stopping you from logging messages as you handle exceptions. The best case of exceptions is easily as good as best case go-style error handling and reporting. The worst case of exceptions is far more informative than the worst case of error messages. I'm not sure what an example that requires great use of some language facility is supposed to be illustrative of - good use of a facility is usually... good? [Edit: this was a reply to a comment you seem to have rewritten (I think for the worse) but I think the response still mostly works]
- lloeki 8y agoI think this can fundamentally be summed up as: errors are "failure as data" (hence, message), and you get to write the flow (including handling and annotating the call stack) vs exceptions are "failure as flow" (hence, stack trace), and you get to write the data (including logging) May very well be paraphrasing a well known maxim about closures and objects as errors are a poor man's exceptions and exceptions are a poor man's errors.