3 ms·
> Also you can't scope it to just part of the function. Why not? func outer() { func() { defer catch() { if r := recov
by randomdata 2y ago
> Also you can't scope it to just part of the function.
Why not?
func outer() {
func() {
defer catch() {
if r := recover(); r != nil {
fmt.Println("Recovered from doSomething:", r)
}
}()
doSomething() // Can panic
}()
func() {
defer catch() {
if r := recover(); r != nil {
fmt.Println("Recovered from doSomethingElse:", r)
}
}()
doSomethingElse() // Can also panic
}()
}
I don't get why we keep getting these "expert" comments from people who have never used Go before.
Hell, if you long for try/catch for some reason, you can even get creative:
func try(fn func(), catch func(any)) {
defer func() {
if r := recover(); r != nil {
catch(r)
}
}()
fn()
}
func outer() {
try(func() {
doSomething()
}, func(r any) {
fmt.Println(r)
})
try(func() {
doSomethingElse()
}, func(r any) {
fmt.Println(r)
})
}
But then you soon start to realize how awful try/catch actually is, so...
- hot_gril 2y agoTry-catch is awful if you're forcing it in a language that doesn't really support it. I provided a JS try-catch example above; is there something wrong with it? The recover is still function-wide in your example, which is what I said. You can nest funcs just to deal with this, but it's ugly, and code reviewers won't like it. I use Go on my team, and yeah I'm not as expert as the team who created Go here, but idk why you keep saying I've never used it. My complaint about "if err" is pretty common among Go users, who would understand the joke of calling it "Errlang."
- randomdata 2y ago> I provided a JS try-catch example above; is there something wrong with it? Yes, it suffers all the same problems. And then doesn't even help you with the errors once you get them! You then have to resort to this kind of craziness to do something with the error: try { doSomething() } catch(error) { if (error instanceof FooError) { console.log('foo') } else if (error instanceof BarError) { console.log('bar') } else if (error instanceof BazError) { console.log('baz') } else { console.log('unknown') } } Which leaves you wondering why you didn't just write: err := doSomething() switch { case errors.Is(err, ErrFoo): fmt.Println("foo") case errors.Is(err, ErrBar): fmt.Println("bar") case errors.Is(err, ErrBaz): fmt.Println("baz") default: fmt.Println("unknown") } At least Java gives you multiple catch blocks to make things slightly more sane. But I get the impression that those who find benefit in passing errors using exception handlers don't handle errors. If you don't have to worry about errors in the code you write, then I think there is a good case to be made that errors as exceptions is a better approach. That is, after all, the difference between scripts and systems. Scripts can simply fail, leaving the user to try again. Errors as exceptions, or something in the same vein, make sense as the predominant mechanism in scripting languages. Systems, on the other, have to deal with failure. You don't get to just bubble it up and let the user deal with it. This is where errors as exceptions becomes a nightmare. Go is unabashedly a systems language. It is not meant to be a scripting language. Different tools for different jobs.
- hot_gril 2y agoThe point of exceptions is to make it convenient to propagate errors upwards and unlikely that you accidentally ignore an error, as discussed in the other thread. This doesn't magically do your error handling too, but the Golang example isn't any nicer. They aren't different jobs, though. The two most common uses of JS are backend systems (like you'd often use Golang for) and web frontends, not scripts. Backends will usually catch errors in one place, an HTTP or similar handler, sending back the appropriate status code with maybe a payload. Golang backends do something similar, which is why you see so much "if err != nil... return err" in practice. Python is more for scripts aka CLIs, but Python backends are fairly common too. And Golang CLIs are also common.
- tsimionescu 2y agoThis Golang guru talk of "handling errors" is almost entirely BS in my experience. I've almost never seen a Go library or code example that does anything other than bubble an error it got from its lower levels up to its callers, with some extra context if you're lucky. The rare exceptions are either some retries for network operations, or just ignoring the error and returning some default value.
- hot_gril 2y agoI hear this in C++ too since we can't use exceptions here. "Unlike some other toy languages, we don't ignore errors, we handle them head-on." Uh no you don't, in fact it took a lot to make people stop ignoring errors or "handling" errors by crashing the entire service. But at least we have a rule checking that you actually did something with the return statuses.
- peterashford 2y agoNo, I think you just showed that trying to use Go as if it was designed to use panic as an exception is ugly. Other languages use exceptions perfectly well and I would say consequently have a much better error handling story than go. I really like go - a lot. But its error handling is truly awful.