Live data from Hacker News

Proposal: A built-in Go error check function, try

github.com

101–110 of 127 posts

Re: Proposal: A built-in Go error check function, try

#101
post #65
post #41

Earlier quoted context omitted.

I don’t like exceptions at all. They do not make it obvious what is going on, I never am completely sure if I’m handling them right. When I want to throw an exception I’m often unsure which would be right, and sometimes your API can have multiple reasons to throw the same exception. Go error handling is not like that. But I can sure as hell say fairly that Go error handling is likely also not similar to what you did…

Yeah, until one realizes that most Go error handling is a mix of - Parsing error results inside strings - if .... else boilerplate - Underscore everywhere to silence them - Abuse from panic, aka exceptions in disguise If you want error handling without exception's guesswork, there are checked exceptions (used for the first time in CLU 1975), and result types (used for the first in ML in 1973) Both without the ceremon…

Parsing error results inside strings

Fair point - this is a nasty result of their simple interface, and I think a mistake given much of the std lib doesn't use concrete types behind the interface. fmt.Errorf leads directly to this. It's simple, but not very flexible and can lead to horrible habits like parsing strings.

if .... else boilerplate

It's more like if boilerplate. People don't tend to use else unless absolutely necessary - it's if err deal with it, otherwise proceed. I agree errors in Go are more verbose than in some other languages, though in practice I don't find this a huge problem. I think I'd prefer result types but you're still handling it in a similar way.

Underscore everywhere to silence them Abuse from panic, aka exceptions in disguise

This is not how Go is used in practice, I mean I'm sure somebody somewhere does this but it is not the norm. I maintain large codebases at work with zero instances of these faults.

Re: Proposal: A built-in Go error check function, try

#102
post #80

Earlier quoted context omitted.

Because it doesn’t skip the call chain - each function must explicitly handle the error or pass it on. In practice usually errors are handled one or two levels up, not with some global error handler as people do with exceptions. Also the error is in the function signature, unlike exceptions. Also, you don’t use try everywhere, that’s the point. They could do with some better examples.

> Because it doesn’t skip the call chain - each function must explicitly handle the error or pass it on So like, checked exceptions? > Also the error is in the function signature, unlike exceptions. So like, checked exceptions?

[deleted]

Re: Proposal: A built-in Go error check function, try

#103
post #65

Earlier quoted context omitted.

Yeah, until one realizes that most Go error handling is a mix of - Parsing error results inside strings - if .... else boilerplate - Underscore everywhere to silence them - Abuse from panic, aka exceptions in disguise If you want error handling without exception's guesswork, there are checked exceptions (used for the first time in CLU 1975), and result types (used for the first in ML in 1973) Both without the ceremon…

You've read a lot of very bad Go code then, that doesn't follow any of the established practices for it. Your list there is almost a primer of "what not to do in Go", and is certainly not representative of the Go code in e.g. the standard library. I sense some frustration about the language... what happened to make you so anti-Go?

> I sense some frustration about the language... what happened to make you so anti-Go?

That's an utterly pointless derailment.

Re: Proposal: A built-in Go error check function, try

#104
post #90

Earlier quoted context omitted.

You've read a lot of very bad Go code then, that doesn't follow any of the established practices for it. Your list there is almost a primer of "what not to do in Go", and is certainly not representative of the Go code in e.g. the standard library. I sense some frustration about the language... what happened to make you so anti-Go?

You mean like this standard library code? https://go.googlesource.com/proposal/+/master/design/go2draf... > I sense some frustration about the language... what happened to make you so anti-Go? Go is C with GC and bounds checking, aka Limbo reborn with some Oberon-2 influence. Already much better for our IT safety than sticking with C, still I kind of expected Google capable of producing Swift, Rust or TypeScript leve…

[deleted]

Re: Proposal: A built-in Go error check function, try

#105
post #92
post #71

Earlier quoted context omitted.

Yeah, they are so reliable. A living proof of good quality. https://www.cvedetails.com/vulnerability-list/opmemc-1/memor...

Linux hasn't segfaulted on me in years. Nor has Python C level (except when I use ctypes to use openssl directly). Nor has gcc, emacs or any of the standard shell commands I use. When I worked in a large C shop writing network servers, we all got emailed whenever our code segfaulted with a stack trace. Now our Java servers routinely catch all exceptions and then need to be restarted for some reason when the network g…

Really?!?

Then you should advise Google on what they are doing wrong.

"The State of Kernel Self Protection Project by Kees Cook, Google"

https://www.youtube.com/watch?v=aMkCKeZ8xZw

Re: Proposal: A built-in Go error check function, try

#106
post #58
post #29

Well, yet another magic function.

It seems so ad hoc. It's not really design when one just papers over a very specific shortcoming.

I agree that overloading the semantics of function calls is ugly, but to play the devil's advocate, does it have to be "design" in that sense if it truly does address the shortcoming in a practically sufficient manner?

Aside from not appealing at all to my sense of esthetics, I have no qualms about this because it does address a problem that a lot of people have complained about in a way that I could get the idea within a couple of minutes of reading the proposal. That said, a keyword might have been nicer.

Re: Proposal: A built-in Go error check function, try

#107
post #52

This is interesting, but I think it doesn't necessarily fit the language well. 1. Go has very few keywords relative to other newish languages like Swift and Kotlin. Introducing a new one should only be done if the benefits are undeniable. 2. It causes an early return without any use of the "return" keyword, which feels pretty weird. 3. It's a bit weird that err will be magically defined in a defer function if the sur…

1. As explained in the proposal, try is not a keyword, but a built-in function. 2. Returning if there is an error is the whole point of this proposal. 3. I don't understand your point. Could you provide an example? 4. try is explicit. There is no implicit behavior or stack unwinding.

it uses the same syntax as functions, but it doesn't behave like a function – functions generally can't manipulate control flow like that. so calling it a function is weird because it's closer to a language construct like `await`

Re: Proposal: A built-in Go error check function, try

#108
post #107
post #52

Earlier quoted context omitted.

1. As explained in the proposal, try is not a keyword, but a built-in function. 2. Returning if there is an error is the whole point of this proposal. 3. I don't understand your point. Could you provide an example? 4. try is explicit. There is no implicit behavior or stack unwinding.

it uses the same syntax as functions, but it doesn't behave like a function – functions generally can't manipulate control flow like that. so calling it a function is weird because it's closer to a language construct like `await`

We already have one built-in function that alters the control flow: panic. But I agree it's a bit weird.

Re: Proposal: A built-in Go error check function, try

#109
post #65
post #41

Earlier quoted context omitted.

I don’t like exceptions at all. They do not make it obvious what is going on, I never am completely sure if I’m handling them right. When I want to throw an exception I’m often unsure which would be right, and sometimes your API can have multiple reasons to throw the same exception. Go error handling is not like that. But I can sure as hell say fairly that Go error handling is likely also not similar to what you did…

Yeah, until one realizes that most Go error handling is a mix of - Parsing error results inside strings - if .... else boilerplate - Underscore everywhere to silence them - Abuse from panic, aka exceptions in disguise If you want error handling without exception's guesswork, there are checked exceptions (used for the first time in CLU 1975), and result types (used for the first in ML in 1973) Both without the ceremon…

>- Parsing error results inside strings

You do not need to parse error results in strings. Many libraries expose structural error types which can be inspected with type switches or other language mechanisms. However, for the most part, you can just treat all errors from a function the same.

There's definitely cases where you can't, like you may want to detect whether or not your error should be retried or treated as a permanent failure. You do the same thing you'd do with an exception: type-switch on the type of error, just like you'd catch on the type of exception. You can also do value comparisons for some errors that are constant, like io.EOF, which is handy in simple cases. The standard library also has some helpers for a couple common cases, like os.IsNotExist for checking if a file error occurred because the file did not exist.

The only time where you really, genuinely would need to parse strings is if you caught panics from the language runtime, which are actually just strings. However, this is unsupported, and the current Go HEAD actually just changed the format of an index out of bounds panic, so it would be very unwise to do this.

Examples of libraries that provide richer errors that satisfy the standard error interface:

- go-pg: https://godoc.org/github.com/go-pg/pg#Error

- elastigo: https://godoc.org/github.com/mattbaird/elastigo/lib#ESError

- redigo: https://godoc.org/github.com/gomodule/redigo/redis#Error (it's a string because the underlying protocol uses error strings.)

- gin: https://godoc.org/github.com/gin-gonic/gin#Error

The first three I picked because I used them, but the last one was fun. I just found one of the top Go libraries on GitHub explore and checked to see if they had a rich error type in their library, and they did. It's definitely common practice.

So yeah, you shouldn't be parsing error strings.

>- if .... else boilerplate

Yes that's the repetition problem that there's proposals to fix, but if that's the worst problem I still find it less annoying than needing this, which requires at least two new scopes:

    try {
        doThing(param[0]);
    } catch(e IOException) {
        Log.Warning(e.message);
        return;
    } catch(e ApiException) {
        throw new InvalidParameterException(String.Format("Invalid parameter: {}", param[0]), e);
    }
Or, even worse, not needing anything at all.

    //  Compiles
    //  No lint warning
    //  Sometimes correct!
    doThing(param[0]);
...Which is not always even bad practice because you may very well want the parent to catch those. But without comments, there's no way for the users of your function to know what to catch unless they inspect the function.

Without inspecting every possible codepath, it is impossible to know which errors are inadvertently not handled, and sometimes it is difficult to tell how a given error will be handled.

The correct thing to do in Go is almost always some variation of this, which is pretty simple:

    err := doThing(param[0])
    if err != nil {
        return err
    }
But these blocks are not invisible, and sometimes it will occur to you while writing it out that it isn't right for a given call site. So you can make it more complicated:

    err := doThing(param[0])
    if err == io.EOF {
        log.Printf("While doing thing: %v", err)
        return err
    } else if err != nil {
        return errors.Wrap(err, fmt.Sprintf("invalid parameter: %v", param[0]))
    }
Go doesn't force correct error handling, but it makes incorrect error handling more obvious, and it certainly makes you aware of error paths.

>- Underscore everywhere to silence them

You shouldn't silence them, unless maybe if you are writing example code. But a lot of examples on the web will just have correct error handling, which seems like a win/win to me.

>- Abuse from panic, aka exceptions in disguise

That's just bad code. You even said 'abuse' yourself.

You can call them exceptions in disguise, but they're really not. This thinking basically implies all error handling that unwinds the stack is “exceptions.” If they were exceptions, presumably you'd love Go error handling, because it has exceptions. Panic is a lot more limited, and generally good software will only catch panics in a couple types of circumstances:

- At API boundary edges when dealing with an API that nests deeply. In this case, you can recover but panic if the error was not an API error. This would allow a library to avoid passing the error value around when the only logical thing to do with the error value is to pass it back to the library user; A good example would be a parser.

- When trying to isolate a failure, for example to prevent one HTTP request from taking down an entire HTTP server.

>If you want error handling without exception's guesswork, there are checked exceptions (used for the first time in CLU 1975), and result types (used for the first in ML in 1973)

Does your language of choice actually support checked exceptions? C#, Python, JavaScript don't. Only modern language I am aware of that does off-hand is Java, and I don't think very much at all uses it, because it is even more annoying than Go error handling.

>Just because they have a very good career, it doesn't make them always right.

No, but it would be awfully strange if they learned nothing from that experience, which is kind of what you implied.

>I tend to think for myself and not from opinions of others.

This is just an empty platitude.

I never claimed that my opinion of Go being good was due to the background of Rob Pike or Bell Labers in general, just pointing out that the point of 'I programmed in the 80s and 90s' seems kind of odd given the background of the language designers.

Go is very opinionated, but I happen to like those opinions, genuinely.

Re: Proposal: A built-in Go error check function, try

#110
post #58

Earlier quoted context omitted.

It seems so ad hoc. It's not really design when one just papers over a very specific shortcoming.

I agree that overloading the semantics of function calls is ugly, but to play the devil's advocate, does it have to be "design" in that sense if it truly does address the shortcoming in a practically sufficient manner? Aside from not appealing at all to my sense of esthetics, I have no qualms about this because it does address a problem that a lot of people have complained about in a way that I could get the idea wit…

I suppose the difference between a "quick fix" in a language and in a codebase, is that the former will be crystalized forever.

Language designers seem to like to bang the drum about the ethos of "Orthogonal Features". I know Go's have, in presentations. But that seems to be cast off when the going gets tough. See also "Contracts" in Go generics, which is mostly the same thing as the existing Interfaces feature, but working around the fact that interfaces didn't have a good story for symbolic operators. Orthogonal? Smorthogonal!

Post reply on HN