5 ms·
Panics can be caught and handled by parent callers and thus behave a little bit like exceptions (not as pretty I'll grant you, but still better than the "no way
by laumars 9y ago
Panics can be caught and handled by parent callers and thus behave a little bit like exceptions (not as pretty I'll grant you, but still better than the "no way out other than aborting the process" approach it seems at first glance). However you generally you don't want to catch panics except under rare conditions because panics are intended to be used in "the world is ending" kind of scenarios (it doesn't always work out this way but that is the theory).
For general error handling there is an error object that gets returned by functions. It leads to the often moaned about syntax below:
if err != nil {
return err
}
Yeah it's ugly. Yeah other languages have try / etc. But for all of it's sins I've found it still gets the job done.
- amelius 9y agoThanks for the explanation. Writing that if-construct after every function call doesn't sound like a lot of fun. In fact it sounds like work! Honestly, I think I'll wait until Go has matured a bit, before I try it for a side-project.
- konart 9y ago>matured a bit If it is not mature enough for you now - it will never be. Right now it is already used in many huge IT companies and extremly popular in China. Writing that if-construct after every function is the design, not the lack of it.
- laumars 9y agoIt's easy to criticise this from a visual glance but you have to remember that proper error handling in any language is hard work and often produces ugly code where you need to account for multiple edge cases - many of which aren't serious enough to cause an exception but would still break the program's logic. All Go does is group these conditions into a standard interface. Furthermore, because Go does unify these conditions, I've found it effective for handling a whole array of differing edge cases that I might have otherwise overlooked. In that regard I've anecdotally found it more effective than most of the habits you see in other languages (I can't say all languages because I haven't used every language out there, but I have developed in excess of a dozen different programming languages over the last 30 years). In short, in Go error handling becomes a first class citizen rather than a byproduct you begrudgingly need to check for. Also while it might not be to everyone's tastes, adding "if err != nil {" really does add practically nothing to your overall dev time in real terms. But I'm not here to advocate one method of error handling over another, nor to try and convince anyone to use Go who might not have otherwise. Obviously you can see I get a little frustrated when people judge it purely on face value but that's because I have spent some time with the language and found it to be surprisingly effective at delivering a stable product.
- amelius 9y ago> Also while it might not be to everyone's tastes, adding "if err != nil {" really does add practically nothing to your overall dev time in real terms. But how do you compose functions then. You can't write: f(g(h(...))) > when people judge it purely on face value Yes, I can see that is frustrating. But I already know the style of programming that requires if-statements instead of exceptions, as I have been programming in C a lot, and I don't want to go back to that style because I'm lazy and I'm sure I will forget to handle some errors. I want my language to deal with this. Honestly, is that really too much to ask? Even javascript has exceptions.
- dullgiulio 9y ago> because I'm lazy and I'm sure I will forget to handle some errors I really think you should try Go before being so convinced about your assertions. It's not easy to forget error handling in Go. And letting exceptions bubble up all the way will improve things how?
- masklinn 9y ago> It's not easy to forget error handling in Go. It's very easy to do so if the function has no useful return value or you don't care for it e.g. Writer.Write: https://play.golang.org/p/cPh0PJoz-v https://play.golang.org/p/cPh0PJoz-v > And letting exceptions bubble up all the way will improve things how? Errors the developer forgets (or does not want) to handle will trigger a default handler.
- garfij 9y agoIn practice, what you end up doing is adding the `errcheck` linter to your build process and it finds all instances of you not dealing with an error return and it's "just-as-good" as a compile time check.
- erik_seaberg 9y agoA stack of ten functions doesn't need to explicitly catch and re-raise the exception ten times to get it to where it can be handled.
- dullgiulio 9y agoUgh, yeah, handling errors sounds like work because it is. But imagine the consequences of a program that doesn't do this work. If it is doing something important, fingers crossed. (Keep in mind: unhandled exceptions are like panics. Not good.)
- kasey_junk 9y agoI don't mind that golang avoids exceptions (it would be better if it didn't have them at all) but I don't understand why they looked around the language landscape and landed on C style return codes as the right path forward. Monadic error handling has all the supposed benefits the return value style errors but allows for easy composition. After years I'm still infuriated with error handling in golang and it was such an easy thing to avoid.
- dragonwriter 9y ago> However you generally you don't want to catch panics except under rare conditions because panics are intended to be used in "the world is ending" kind of scenarios Strange, I've always heard the opposite: if you write a function that can panic, you always want to handle it in your code that calls the function (which should be the only code that could) because panics should generally not be exposed across a public interface, including the boundary between the top-level Go code to the outside world.
- baby 9y agopanics are like asserts. They're here to make sure the program is being used correctly. There is no handling of them, if it's not used correctly you crash. Of course you do not want to use panic in sensitive code. The best example is looking at how panic() is used in crypto/tls (which has a lot of sensitive code! You really don't want a client to be able to crash a server): https://gist.github.com/mimoo/93c33d88222c87fb384b4ca3b04fb5ff https://gist.github.com/mimoo/93c33d88222c87fb384b4ca3b04fb5...
- gmfawcett 9y agoThat's simply not true. There is no recovering from a failed assert. Go's recover() allows recovering from panics. Further, it is considered good practice to recover from panics within library API boundaries, and return errors across the API instead. "The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values."[1] [1] https://blog.golang.org/defer-panic-and-recover https://blog.golang.org/defer-panic-and-recover
- NateDad 9y agoYes, if you use panics for control flow in your package, you need to recover from them and hide that fact from your API. That is not the same as saying that you should recover from any panics that happen inside your library. Unexpected panics basically always indicate a programmer error.
- 9y ago