8 ms·
Go 1.13: xerrors
- albeebe1 7y agoSpeaking of errors, here's how i approach writing a good error message. Fill in the blank "Well basically what happened is ___________" For example i've found this has helped me to go from "Invalid phone number" to "The phone number needs to be 10 digits"
- chisleu 7y agoDescriptive errors that match the business logic are ideal in many cases. Clearly, one shouldn't don't divulge "secret" validators. More on the topic, I'm really happy to see this coming in so far ahead of 2.0. I want to get ready for 2.0 because of the gains I hope to see in idiomatic go in 2.0.
- SamWhited 7y agoThis is the general strategy when developing "2.0": do as much as possible in a backwards compatible way, and if we never need to make a breaking change, never call a release 2.0. The new features process that was introduced recently may result in a 2.0 release, or it may result in 1.999, so you will continue to see new features in each release for a while regardless of what the release is called.
- jerf 7y agoOne of the things I picked up from Dave Winer around 20 years ago is that errors messages should be of the form "Can't X because Y", and while I don't quite always use that exact grammar form, my errors pretty much all take that form when there isn't some other overriding local standard for errors. It's not a bad template. Most error messages will give you some hint about the Y, but the difference between "Error: file system full" and "Error: couldn't open log file '/var/log/myapp.log' because: file system full" is pretty substantial, especially if system state has mutated in the meantime and by the time you get to the system, none of the filesystems are full anymore.
- spullara 7y agoThe biggest issue I have with most error messages is that they say things like you have here but don't reflect back the data that caused the error, i.e. show me the phone number you think I sent you.
- mattnewton 7y agoI think this context is really hard to carry around, and if you aren’t extra super careful you can end up leaking passwords and other secret bits of memory here to logs. Better to just give me a place to put a debugger breakpoint IMO.
- whatupdave 7y agoHave to be careful here, this would send phone numbers into logs files and other potential downstream services which is a bit of a GDPR nightmare now.
- nickcw 7y agoThis (it looks like to me) is an attempt to pull in the best bits of Dave Cheney's errors package (which I love) into the standard library: https://github.com/pkg/errors https://github.com/pkg/errors Standardising error unwrapping is a great idea IMHO and I think that this has a lot of merit. I don't like the `fmt.Errorf("more description: %w", err)` though for several reasons. Firstly it is a lot more opaque than Dave Cheney's original mechanism errors.Wrap(err, "more description"). You've got to check the format string for a `%w` to see if it is wrapping an error or not. Secondly why is this really important functionality in `fmt` and not in `error`? And finally we've been encouraged to write `fmt.Errorf("more description: %v", err)` (note `%v` not `%w`), so I think there will be a lot of unwrapped errors. ... I'm not sure enough has been thought about the backwards incompatibility. With rclone I try to maintain compatibility with the current go release and a few previous ones so that rclone can remain running with distro go versions and gccgo both of which are a bit behind. For something as common as error handling this will cause lots of libraries to suddenly be no longer usable with anything less than go1.13. IMHO I think this would be better staying as a non standard library package for the time being while more kinks are worked out.
- TheSwordsman 7y ago+1 on all of this. I really prefer that https://github.com/pkg/errors https://github.com/pkg/errors is outside of the standard library so I don't need to use the fmt.Errorf abomination.
- insertnickname 7y ago>Secondly why is this really important functionality in `fmt` and not in `error`? `fmt` already depends on `errors`, and Go does not allow cyclical dependencies, so `errors` would have to reimplement string formatting.
- masklinn 7y agoOr they could move the machinery into a shared module. Which already exists incidentally, internal/errinternal was added so errors.New and fmt.Errorf could return the same type. It does make errors pull the entire formatting machinery, but chances are you're probably using string formatting long before errors so meh…
- spyspy 7y agoThis seems way better than the other proposals. pkg/errors solved every complaint I had about errors years ago.
- binwiederhier 7y agoAs others have stated, this seems incredibly odd to me: > If the last argument is an error and the format string ends with ": %w", ... This seems like a magic-string kinda hack to me. I like the idea of wrapping errors so that you keep the stack and full context, especially since you may need additional structured data from all errors (e.g. DB error, access error, ...) to produce user facing messages, so IMHO the wrapping should be more explicit than just %w.
- jerf 7y agoIt is. It's a backwards-compatibility magic string hack. I would suggest new code uses the new, formal ways of obtaining the same result. (I'm not defending it so much as explaining it. I'm not sure how I feel about it myself.)
- smudgymcscmudge 7y ago> I would suggest new code uses the new, formal ways of obtaining the same result I missed that. How else do you wrap an error with xerrors?
- llimllib 7y agoreturn errors.Wrap(err, "read failed")
- smudgymcscmudge 7y agoThat's what I do now with pkg/errors, but I don't see a xerrors.Wrap in the docs or any mention of it in the proposal.
- jerf 7y agoMy apologies, I seem to have confused the two packages. I don't see it in the godoc either. In which case I echo your desire to have an explicit method of formatting and wrapping. I suppose it won't take long for a component of one of the gometalinter or golang-ci or whatever to develop a "Errorf used without %w in the final position" warning, which will be good enough for me, but it would be better to have something like Wrap officially, IMHO.
- trpc 7y agoIt seems like golang designers are totally isolated from what's been happening in the last 30 years in languages design. They still insist on their weird way of error handling just like they were stubborn for years and years on the lack of package management and eventually a very weird and rudimentary way of it. It's sad because I use this language extensively but its weirdly mediocre design is totally unfathomable. It's like they are very stubborn to do anything but the right thing.
- icholy 7y ago> I use this language extensively but its weirdly mediocre design is totally unfathomable. So then why do you use it extensively?
- trpc 7y agobecause I use it in my day job, not by choice.
- pkaye 7y agoSo what language do you think does everything the right way?
- deleted 7y ago[deleted]
- apta 7y agoThat's a stawman fallacy. There is no perfect language. However, there are languages that almost are strictly superior to others. Java and C# in this case are almost strictly superior to golang in almost every front.
- AsyncAwait 7y agoWell, unless you consider Go's concurrency model superior, as well as the fact that you get native binaries.
- networkimprov 7y agoFrom what I have seen, the Go 2 Error Values plan[1] has not received enough exposure to generate the level of feedback necessary to support a go/no-go decision re a major change in 1.13 -- one we cannot opt-out of, at that. I suspect that the overwhelming majority of Go developers has no idea this is in the works. It was covered once on the blog last August in the Draft Design summary, when there wasn't any code behind it. It was not mentioned in Go 2 Here We Come[2], nor at the start of the below golang-dev thread. It was mentioned on golang-dev when I posted a link to the issue tracker in late January, but my posts would see a fraction of the attention vs those by Rob, Robert, Russ, Ian, et al. There are outstanding issues with the current draft, specifically its performance[3] and API[4]. If it lands in 1.13, please give it Experimental status, with a build or env flag to disable changes to existing APIs, and perhaps a way to re-enable them on a per-function or per-package basis. [1] https://github.com/golang/go/issues/29934 https://github.com/golang/go/issues/29934 [2] https://blog.golang.org/go2-here-we-come https://blog.golang.org/go2-here-we-come [3] https://github.com/golang/go/issues/29934#issuecomment-486503822 https://github.com/golang/go/issues/29934#issuecomment-48650... [4] https://github.com/golang/go/issues/29934#issuecomment-483509242 https://github.com/golang/go/issues/29934#issuecomment-48350... . [Originally posted on golang-dev, in response to "Last call for feedback on Go 1.13..."] https://groups.google.com/d/topic/golang-dev/jPY0RYXSvCU/discussion https://groups.google.com/d/topic/golang-dev/jPY0RYXSvCU/dis...
- admax88q 7y agoGo error handling. Slowly re-inventing Java's exceptions one use case at a time.
- zzzcpan 7y agoWeirdly enough this perspective might suggest that the problem is not actually with Go, but with object oriented programming. Which wasn't considered thoroughly by original authors, because they were not OO programmers.
- admax88q 7y agoNo other paradigm appears to be able to handle the complexity required to build the systems of today. Objects are very natural way to organize complexity. It's what let UNIX succeed where Multics failed.
- smilekzs 7y agoI agree with the feeling, but I also see this being a debate between an opt-in approach (choose to use an error value with gradually more information enclosed) vs opt-out (throw an Exception, a la C#/Java, that by default stores everything you may or may not need, then maybe figure out a way to stop storing what you don't need). The use cases are not going to magically go away though, which explains why we need the solution to be somewhere in the middle.
- admax88q 7y ago> then maybe figure out a way to stop storing what you don't need I'm not sure I understand why this is something you need to do. "Figure out a way to stop storing what you don't need." Who cares if you don't need it, or at least don't need it now, storage is cheap.
- apta 7y agoExactly. Plus, code that uses exceptions but does not encounter any throws should be faster than code that uses error checks. In the latter, there's always a cost even if there aren't any errors returned. However, the former can optimize for the (hopefully more common path) of no exceptions being thrown and avoid checks altogether.
- lenkite 7y agoI think this is a positive development and should be cheered by Go programmers. Slowly but surely they progress on the road to implementing Exceptions. (ducks and runs like a scaredy cat to avoid the wrath of Go Fans)
- teabee89 7y agoWhat I'm really looking for is being able to debug any production Go binary by inspecting the stack trace behind an error. Could be gated by an environment variable.
- acroback 7y agoNot sure why people are bashing Go because of it's choices. Looking forward to shit storm once they introduce generics in near future. I am sure people will still complain that this is not how parametric polymorphism should be implemented.