Rolling your own error library is trivial. We have a great one at work that works great, prints stack traces, interops with normal error handlers, and does a lot of custom work for translating errors into external customer-visible messages and internal developer messages. We use it at every layer of a 50-60 grpc microservice ecosystem without much headache.
Catching deferred errors is trivial, not sure what you mean there:
defer func () {
err := f.Close()
...
}()Printing stack traces is like 4 lines, I was able to implement ours in 60 minutes of doc skimming. Now it'd be 5 minutes.
I don't understand your last two sentences. It doesn't reflect anything I've run into in the real world, I don't think.
I have a few gripes about golang, but the minimalist error interface is not one of them.
And right there is where you’re going to lose most people.
If it’s is trivial, why isn’t in the standard library? If everyone needs to do it, why not standardize? I love Go, but i have to agree with grandparent poster.
Getting a stack trace is available in the runtime/debug library.
Perhaps stack traces aren't in normal errors since a program can throw 1,000 errors per second in a perfectly functioning application and that could get expensive.
I have heard that performance is the reason but I'm not able to confirm that.
github.com/pkg/errors is fairly ubiquitous and includes stack traces.
> If everyone needs to do it, why not standardize
The only time I've needed to read the stack trace in go, is when there has been an unexpected panic. Otherwise my error messages are more than sufficient to find the root cause of the error. I only have to run my own code though, I imagine if I was debugging someone elses code the stacktrace would be invaluable.
Go has purposely tried to do a few things differently. Date format comes to mind, and lack of exceptions which I personally like.
Trivial does not mean generic. Just because error handling is easy doesn't mean I want the same handling as you do.
Error handling is generic by itself. This is at the heart of any existing application. It is fundamental part of the design process and later on contributes greatly to troubleshooting. Making this solid should be, IMHO, one of the most important and thought through part of any language. In Go it seems to be left at the developer's convenience. And even though you may say there is a huge debate on the subject, it always leads to nothing. Or almost nothing, like in this case. It's just disappointing.
If people don't agree then it by definition does not belong in the stdlib.
I guess I finished that sentence in a different way than I started it.
For example, no one likes gofmt (tabs, eww), but everyone likes code across packages looking the same. And so we use it.
https://play.golang.org/p/7Gs76Nt-h4b
That issue is one of the reasons everything has to return 'error', not your own struct that might be more convenient to work with. I've run into it in the wild in dozens of codebases, so it's definitely a real issue.
Without generics and covariance, it's an uphill battle to create usable monadic error handling in Go. If all you've used before is C which has int returns and globals for error handling, I can see how go's error handling looks nice, but compared to most languages invented in the last 20 years, it feels far worse.
Sounds like the C and C++ situation where each company and large project rolls out their own string implementation.
There are still stuff missing, but not basic low level stuff that everyone uses daily.
Minimalist standard library doesn't go well with their philosophy around dependency (“a little copying is better than a little dependency”). That's why the made so much stuff in std.
When working in other programming languages, this is something I sorely miss and have to resort to ugly and non intuitive try catch constructs which feel like "bolt-on magic" rather than a natural part if the program.
IMO this feature makes up for most of the stuff that's lacking.
I'm not sure where you're going with the stack traces complainr. It is pretty trivial to get it in Go.
Treating errors as value is cool (no exception!) but using multiple values not so much, the proper way to do so is with product types, but Go's type system don't have them unfortunately…