Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Returned error values are sometimes errors.New (e.g. io.EOF) and sometimes random fmt.Errorf strings that couldn't possibly be handled (e.g. all of tls.go basically), sometimes actual structs (e.g. PathError),

This is the advantage of having errors be interfaces rather than concrete values. Once you learn how to use it, it's a strength. The usage of structs that satisfy the interface (as in PathError) is clearly documented and completely predictable. If your concern is that a certain package could use a struct satisfying the interface and does not, well, one advantage of errors as interfaces is that you could propose this change without breaking the backwards compatibility guarantee.

It's really important to keep in mind that errors are adopted from error values in C, which means that their idioms and usage is inspired by that rather than by exception handling. Many new Go programmers (including me, when I started) were more familiar with exception handling in higher-level languages than error handling in idiomatic C, so it does take some getting used to.

> and sometimes panics.

Do you have any examples of the standard library using panics to signal handle-able errors (not counting cases in which the panic is recovered at the top-level in the library and never visible to the caller)?

> The math library, as mentioned above, is pretty darn iffy.

The only complaint I have had about package "math" is that all operations are defined on float64s, which can be annoying, but is far better than any alternative. That's an annoyance, but it's certainly not an inconsistency in the library.

Do you have any other examples of inconsistencies in the math package?



Yeah, but with C's old-school int values for errors, you can always make an equality comparison. The error interface in Go doesn't specify equality, so you can do "if err == io.EOF" in some cases and you're up a creek in other cases. Sure you can do if err.Error() == "String I'm expecting", but as the parent said, fmt.Errorf can easily make that impossible.


No, the advantage of having an interface is everything can return an error I can typeswitch on. Unfortunately, you can't (in a backwards compatible way) change io.EOF or any of the other 'constant' errors because there's so much code doing 'if err != io.EOF' which now breaks. In addition, it's backwards incompatible due to anyone doing 'reflect.TypeOf' which I guess you could argue is fine to break.

Speaking of reflection, there's a metric TON of runtime panics in the reflect package. Hell, I'm not sure there's a method in there that can't panic.

No doubt, however, you'll say that's cheating and the expected behavior of that package, so how about NewTimer (playground https://play.golang.org/p/jDKniK3aqa ). It does not give me an opportunity to recover from bad input by passing an error out, it just panics. It is also not documented that it panics afaik and other functions in time (time.Sleep) take negative durations and handle them just fine. This is definitely inconsistent with other std library functions that can take bad input and return errors.

I also think it's disingenuous to say "Keep in mind errors are from C and at least they're better than C"... the comment I'm responding to is a comment regarding go std library being one of the most consistent (implicit compared to ANY LANGUAGE) so I may bring in anything I wish, and sure Go's errors are a step up from C, but they're awful compared to other languages. They're basically passing around strings with no builtin way to create a trace of errors to return up the stack to maybe be printed, no default way to create an optional type with an error value, and no consistent way to determine which of N errors it was that was returned from a function without using a regexp 90% of the time because that damned fmt.Errorf / errors.New... And yes, using a Regexp in your error handling IS a problem.

> defined on float64, which can be annoying, but is far better than any alternative

Funnily enough, the 'rand' library implements everything by just having multiple functions and postfixing them with types (rand.Uint32, rand.Int, rand.Float32) and strconv does something vaguely similar.

Whether one or the other is better, that's another inconsistency in the stdlibrary; do you have many functions per type or only one function for one type? I have no clue how Go could have abused you such that you are able to conceive of not having a builtin int64 compatible 'min' function as a good thing.

Actually, perhaps your post is simply a plea for help as Go has tied you up and holds a gun to your head, in which case I suppose we should mount a rescue mission forthwith! Just let me write a quick timer to keep track of our progress... -1 you s.. err panic


I don't know about consistency within the standard library, but NewTimer's behavior definitely sounds consistent with the concept of distinguishing programming errors from exceptional conditions. Passing a negative number as a duration could either be defined behavior (equivalent to zero for programmer convenience and consistency with the principle that timers can fire late) or a programming error (should've checked that whatever you were subtracting to get that duration isn't backwards), but it's not an exceptional condition that can't be predicted in advance. Indeed, checking for a negative number, which is rarely necessary, is no more code than the 'if err' thing, and if it isn't necessary in a particular use of the function, you have the luxury of knowing it can't fail, and you don't need to figure out what will happen if it does.

(I bet you'd be unhappy at Rust irrecoverably panicking the thread for simply performing addition, if the result overflows!)


    $ curl http://golang.org/pkg/reflect/ | grep panic | wc -l
    79


> Do you have any examples of the standard library using panics to signal handle-able errors

Are those 79 handle-able errors, or are they programming mistakes?


> It's really important to keep in mind that errors are adopted from error values in C, which means that their idioms and usage is inspired by that rather than by exception handling. Many new Go programmers (including me, when I started) were more familiar with exception handling in higher-level languages than error handling in idiomatic C, so it does take some getting used to.

It's also important to keep in mind that people who don't like Go's approach to error handling might not be in favour of the exception-handling way, either. :)

https://news.ycombinator.com/item?id=9439948




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: