error handling thoughts

147 views
Skip to first unread message

Steve Roth

unread,
Jul 27, 2023, 11:04:19 AM7/27/23
to golang-nuts
The ongoing Go survey asked a question about satisfaction with error handling in Go.  I'd like to express an opinion on it that I haven't seen elsewhere, for which there was not room in the survey.

I am generally a fan of the explicit error handling code in Go, but I get frustrated by the interactions between error handling, := assignments, and compiler warnings.  My preferred way of writing the standard clause is

if err := fn(); err != nil {
    // handle error and bail out
}

However, often the function in question returns a result I want to work with.  If it's something important for the whole rest of the function, I'll probably just define it as a variable at function scope:

var (
    result sometype
    err error
)
// ...
if result, err = fn(); err != nil {
    // handle error and bail out
}
// act on result

But often, the result is something I'm only going to use for one statement and is not a variable of significance to the whole function.  Those are the sorts of cases that := is best for, in my opinion.  In those cases, what I'd like to write is

if result, err := fn(); err != nil {
    // handle error and bail out
} else {
    // act on result
}

Unfortunately, the compiler gives a warning on that.  Because the truth clause bailed out (e.g., "return"), it insists that I remove the else and turn the code into

if result, err := fn(); err != nil {
    // handle error and bail out
}
// act on result

But that doesn't compile because result is no longer in scope.

What I often wind up doing instead is

if result, err = fn(); err == nil {
    // act on result
} else {
    // handle error and bail out
}

That works, but it leaves my code with a mixture of "handle error case first, then success" and "handle success case first, then error" patterns, which I find adds a lot to cognitive load.

I have no idea whether others share my frustration on this admittedly minor point.  But since the survey prodded me, I thought I would voice it and see what reactions it gets.  For me, the ideal solution would be to suppress the compiler warning about removing the else, when doing so would break the code altogether.

Regards,
Steve

Stephen Illingworth

unread,
Jul 27, 2023, 11:34:27 AM7/27/23
to golang-nuts
Hi Steve,

What's the compiler error that you're seeing?

Here's a go playground example of your scenario. It doesn't seem to cause any issues but maybe I'm misunderstanding.


Regards, Stephen

Axel Wagner

unread,
Jul 27, 2023, 1:20:30 PM7/27/23
to Stephen Illingworth, golang-nuts
It's not a compiler error, but OP is probably referring to golint.
FWIW I also prefer the `if v, err := fn(); err != nil { … }` form, in general, but in cases like these I just write

v, err := fn()
if err != nil {
    // handle error and return
}
// do thing with v

I honestly don't see a huge problem with that.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/3a98bae6-8ca9-49d4-8a32-c95ae8863baen%40googlegroups.com.

Ian Lance Taylor

unread,
Jul 27, 2023, 6:55:41 PM7/27/23
to Steve Roth, golang-nuts
On Thu, Jul 27, 2023 at 8:04 AM Steve Roth <st...@rothskeller.net> wrote:
>
> In those cases, what I'd like to write is
>
> if result, err := fn(); err != nil {
>
> // handle error and bail out
>
> } else {
>
> // act on result
> }
>
>
> Unfortunately, the compiler gives a warning on that.

As others have pointed out, the compiler does not give such an error.
The error must be coming from some other tool. If you tell us what
tool that is, perhaps we can fix it. In general a tool should not
recommend removing the else clause from an if statement with a simple
statement that declares variables if the else clause refers to any of
those variables.

Ian

Steve Roth

unread,
Jul 27, 2023, 7:18:24 PM7/27/23
to golang-nuts
The warning that I described is one presented by Visual Studio Code with the vscode-go extension.  Color me stupid for having simply assumed it came from the compiler.  Based on responses to this thread, I looked more closely, and found that Mr. Wagner is correct:  it's coming from golint.

I see that golint is deprecated and frozen.  I'm not sure why my vscode-go is using it, in that case.  Perhaps it's a vestige in my vscode-go configuration from long ago when it wasn't deprecated.  I hope it's not used by fresh installs.  At any rate, disabling it seems straightforward.

Thanks, all, for the responses.
Steve

Reply all
Reply to author
Forward
0 new messages