Why we don't have simple throws error statement

429 views
Skip to first unread message

semi...@gmail.com

unread,
Jul 31, 2020, 10:06:33 AM7/31/20
to golang-nuts
Hey Community,

I know, there are so many discussion about error handling. I read tons of idea about that. Looks like most of idea rejected from community but every idea brings our goal closer.

May be we need simple solution. I like Go's simplest ways always. I don't think so we need complex solution about that. Could we handle complexity the error checking with simple throws statement?


func myFileRDWRFunc(filename string) (string, error) {
   f, err := os.OpenFile(filename, os.O_RDWR, 0600)
   if err != nil { // backward compatibility
       return "", err
   }

    throws func(err error) { // catch all errors
       log.Println(err)
       f.Close()

        return "", err
   }()

    f.WriteString("anystring")
   f.Seek(0, 0)
    b := ioutil.ReadAll(f)

    return string(b), nil
}

Cheers.

Semih.

Yasar Semih Alev

unread,
Jul 31, 2020, 11:47:50 AM7/31/20
to golang-nuts
Note; I don't want to send any proposal currently. Firstly, I would like to share and discuss my idea with community.

Brian Candler

unread,
Jul 31, 2020, 4:25:26 PM7/31/20
to golang-nuts
On Friday, 31 July 2020 15:06:33 UTC+1, semi...@gmail.com wrote:
I know, there are so many discussion about error handling. I read tons of idea about that. Looks like most of idea rejected from community but every idea brings our goal closer.

The more I use go's existing error handling, the more I like it.

It's clear and it's explicit.  Could a function return an error, or not? It's right there in the function signature.  It's something you can't ignore.

    foo := func()        // fails to compile if foo returns two values
    foo, err := func()   // OK, but will fail if you don't use the 'err' value
    foo, _ := func()     // explicitly ignore the error: a big code smell signal
 
You then make a decision as to what to do.  Should I just return from my own function and let the error propagate up unchanged?  Should I propagate a new error which wraps or replaces the original error?  Should I do something else?

There have been dozens of proposals for changing it, and I've not seen one which is as clear or as simple.

For your "throws func" - you didn't describe the semantics.  I am guessing it is intended to be equivalent to the following?

func myFileRDWRFunc(filename string) (string, error) {
    f, err := os.OpenFile(filename, os.O_RDWR, 0600)
    if err != nil { // backward compatibility (??)
        return "", err
    }

    err = f.WriteString("anystring")
    if err != nil {
        log.Println(err)
        f.Close()
        return "", err
    }

    err = f.Seek(0, 0)
    if err != nil {
        log.Println(err)
        f.Close()
        return "", err
    }

    b, err := ioutil.ReadAll(f)
    if err != nil {
        log.Println(err)
        f.Close()
        return "", err
    }

    return string(b), nil
}

That is: I think you're saying IF there's a multi-valued function return, AND the last value is an error, THEN it will silently consume that value, and jump to the handler if not nil.  Is that correct?  What about functions which return multiple values but the last one is not an error?  What happens if the handler doesn't have a "return" statement - does it continue where it left off??

Aside: I don't think putting f.Close() in the error handler is right.  There should be "defer f.Close()" as soon as the file has been opened - so that it is closed both in normal and error conditions.

Yasar Semih Alev

unread,
Aug 1, 2020, 8:51:52 AM8/1/20
to golang-nuts
I did not see clear and simple either.  As I wrote, I don't like complex solutions. Just trying to ask: why we don't have simple solution. The function just simple example, this isn't a draft or something.

Brian Candler

unread,
Aug 1, 2020, 10:46:25 AM8/1/20
to golang-nuts
I think that's because no-one has been able to come up with a detailed, specific proposal where the end result is both simple and clear, when compared to the current situation.

My idea, if it's worth anything, is to have Python-style post conditionals:

return "", err if err != nil

I expect it has already been raised, and rejected for good reasons.  I remember seeing a proposal to change gofmt to format this as a single line:

if err != nil { return "", err }

Carla Pfaff

unread,
Aug 1, 2020, 11:32:19 AM8/1/20
to golang-nuts
Your "throws" statement (why is it called "throws" when it "catches" according to the comment?) looks a lot like the "handle" block from the first draft design by the Go team: the check/handle proposal.

lgo...@gmail.com

unread,
Aug 1, 2020, 1:59:19 PM8/1/20
to golang-nuts
Has anyone ever tallied the number of different forum threads related to changing Go error handling ?  
The current method is obviously a vexing issue to many Go users, and
It seems silly that this issue has never been resolved by the Go team beyond maintaining the status quo... despite, IMHO, several good alternatives that have been suggested on this very forum.

Ian Lance Taylor

unread,
Aug 1, 2020, 2:31:54 PM8/1/20
to lgo...@gmail.com, golang-nuts
On Sat, Aug 1, 2020 at 10:59 AM <lgo...@gmail.com> wrote:
>
> Has anyone ever tallied the number of different forum threads related to changing Go error handling ?
> The current method is obviously a vexing issue to many Go users, and
> It seems silly that this issue has never been resolved by the Go team beyond maintaining the status quo... despite, IMHO, several good alternatives that have been suggested on this very forum.

There have been many alternatives suggested, but none of them have
been clearly better.

I recently wrote a brief overview at https://golang.org/issue/40432.

Ian

David Skinner

unread,
Aug 1, 2020, 8:55:59 PM8/1/20
to golang-nuts
I do not consider error handling an issue but then again I tend to either use the Doit() err{} or MustDoit(){} panic and then use  DI (dependency injection implemented by interface) for error-handling so that I can get an email when we get a new error. So then it would be MustDoit(errorHandler("ConIo")){} 

Actually I suppose it is an issue, I do not do error handling in Go, but my preprocessor converts it to Go. Go error handling can do anything, the implementation may not be clear and that may be the real problem. We can change it by improving the language or by training programmers on recognizing useful abstractions, may need both.

Denis Cheremisov

unread,
Aug 2, 2020, 4:44:43 AM8/2/20
to golang-nuts
There are two major issues with Go error handling:

  1. It is not strict enough, i.e. the compiler cannot ensure error check
  2. It is not consistent enough.
In the first you can easily ignore an error and the compiler will let you go further. In the second, you can both

if err := doSomething(); err != nil {
}

and

v, err := returnSomething()
if err != nil {
}

or err would do this better for sure

doSomething() or err {
}

and

v := returnSomething() or err {
}

воскресенье, 2 августа 2020 г. в 03:55:59 UTC+3, skinne...@gmail.com:
Message has been deleted

Yasar Semih Alev

unread,
Aug 18, 2020, 6:33:54 AM8/18/20
to golang-nuts
Another idea, if we use blank identifier for errors then throws statement catch these with caller function name.

func printSum(a, b, c string) error {
     throws func(caller string, err error) {
         fmt.Println("caller:", caller, err)
         return err
     }()

     x, _ := strconv.Atoi(a)
     y, _ := strconv.Atoi(b)
     z, err := strconv.Atoi(c)
     if err != nil {
         return err
     }

     fmt.Println("result:", x + y + z)

     return nil
}

How is sound?

Semih.

Denis Cheremisov

unread,
Aug 18, 2020, 2:12:29 PM8/18/20
to golang-nuts

Even worse: no idea where the error actually happened.
вторник, 18 августа 2020 г. в 13:33:54 UTC+3, semi...@gmail.com:
Reply all
Reply to author
Forward
0 new messages