Live data from Hacker News

Discussion: Reduce error handling boilerplate in Golang using '?'

github.com

91–94 of 94 posts

Re: Discussion: Reduce error handling boilerplate in Golang using '?'

#91
post #5

It saddens me tbat the default error handler is "return err", as opposed to something that appends context/stack trace. We've converted a few scripts and webapps from Python to Go, and if one does default handling ("return err") the error logs became significantly less useful, compared to exception backtraces. Yes, there are ways around it, but most tutorials don't show them.

Stack traces are expensive . You need to make a conscious decision whether you want a stack trace attached to a particular error (and possibly where it gets attached, if you want it higher in the call chain), which aligns with Go's design philosophy for error handling.

C++-style stack traces, with stack walking and ELF section analysis, are expensive. Python's stack traces, which also involve reading source files from disk, are expensive as well.

But go's do not have to be. A compiler can expand "foo()?" to something like:

err := foo(); if err != nil { return err.WithStringContext("foo() in MyFile.go:25"); }

The only complexity there is appending a constant pointer to "err", and this only happens in error case that uses "?". Depending on implementation it could be a single word write, if compiler can prove there are no other users of "err".

(And if your code is carefully written to be allocation-free and appending a pointer kills that? In this case, you don't have to use "?", put "return err" directly.)

Re: Discussion: Reduce error handling boilerplate in Golang using '?'

#92
post #85

Earlier quoted context omitted.

> I have read this exact claim before, for what it is worth. Did you end up here simply because you repeated what you saw elsewhere without actually thinking about it? I can't tell if you're being intentionally obtuse. It behooves you to research the topic being discussed, instead of writing long-winded snarky posts. It is not worth continuing this discussion unless you can demonstrate, with explicit code examples, w…

Okay, sure. Here is an explicit code example: func foo(bar func() error) bool { err := bar() if err != nil { return true } return false } func TestFooReturnsTrueWhenBarReturnsError(t *testing.T) { if foo(func() error { return nil }) { t.Error("expected foo to return false") } if !foo(func() error { return errors.New("error") }) { t.Error("expected foo to return true") } } Now it is your turn. Modify the body of funct…

That is not what is being discussed and you know it.

Provide an example backing up your claim regarding pattern matching + union types:

> Like in the same way you might forget to write pattern matching code?

Re: Discussion: Reduce error handling boilerplate in Golang using '?'

#93
post #85

Earlier quoted context omitted.

Okay, sure. Here is an explicit code example: func foo(bar func() error) bool { err := bar() if err != nil { return true } return false } func TestFooReturnsTrueWhenBarReturnsError(t *testing.T) { if foo(func() error { return nil }) { t.Error("expected foo to return false") } if !foo(func() error { return errors.New("error") }) { t.Error("expected foo to return true") } } Now it is your turn. Modify the body of funct…

That is not what is being discussed and you know it. Provide an example backing up your claim regarding pattern matching + union types: > Like in the same way you might forget to write pattern matching code?

> That is not what is being discussed and you know it.

That is exactly what is being discussed. Why would the topic arbitrarily change? In case you have forgotten, my literal question/assertion was:

"How would you forget, exactly? Your tests are going to blow in your face should you ever leave out an entire feature from the implementation."

Go on, show us: How would you forget?

> Provide an example backing up your claim regarding pattern matching + union types:

Uh... Okay. Sure? Strange request, but here is an example in CrabLang that meets your ask:

    let result = foo();
    match result {
        Ok(value) => println!("Result: {}", value),
    }
There you go. I forgot to check the error.

Like I said in the full comment that you quoted from, you'll soon recognize your forgetfulness once you apply your checks and balances, but for that brief moment in between it is possible to forget. It must be that way else it would be impossible to input the program. If that's what you think we're talking about... Why? And let me ask again like I did in the comment you quoted from: What is the significance of that? If you had carried that quote through you'd also see: "That's not a real problem." I stand by that. Why not you?

Re: Discussion: Reduce error handling boilerplate in Golang using '?'

#94
post #93

Earlier quoted context omitted.

That is not what is being discussed and you know it. Provide an example backing up your claim regarding pattern matching + union types: > Like in the same way you might forget to write pattern matching code?

> That is not what is being discussed and you know it. That is exactly what is being discussed. Why would the topic arbitrarily change? In case you have forgotten, my literal question/assertion was: "How would you forget, exactly? Your tests are going to blow in your face should you ever leave out an entire feature from the implementation." Go on, show us: How would you forget? > Provide an example backing up your cl…

I'm not sure what the other commenter's point is. If you're checking if the error is nil, or pattern matching on the result of a call, it feels like exactly the same.

In your CrabLang example, you don't have warnings on (I assume they exist) for completion or whatever. There's still the Err case that should at least throw a warning for not being caught.

Post reply on HN