...Go is not perfect. But there is subtle magic in this error business.
Developers should look closely at errors. Imagine handling them as if you
were a doctor and the error was a child's symptom or a test result. Choices:

1. Ask them how they feel, ignore it. Do a test, ignore it. Effectively you
are saying "you are well" even if they're not breathing.

x, _ := ResultAndErr(a,b,c)


2. Ask them if they feel great and if all test results are normal. If not,
send them home.

x, err := ResultAndErr(a,b,c)
if err != nil {
    return
}


3. Ask them if they feel great and if all test results are normal. If not,
send them to a hospital where they can talk to a real doctor.

x, err := ResultAndErr(a,b,c)
if err != nil {
    log.Error(err, a,b,c) // or return err
}


4. Ask them how the feel and if not good, do tests. Then TREAT THEIR
CONDITION.


x, err := ResultAndErr(a,b,c)
if err ==FirstPossibleProblem {
    // HANDLE error1 // reset power, wait, etc.
} else if err ==SecondPossibleProblem {
    // HANDLE error2 // lower temperature, send text, start siren, ...
}
:


These four kinds of doctors closely parallel four kinds of programmers.

On Tue, Sep 5, 2017 at 3:47 PM, Dorival Pedroso <pedr...@cpmech.com> wrote:

> Since *defer* "is the last thing to happen", I think this code is all
> right:
>
> func something() (x int, err error) {
>     watch err != nil {
>         return
>     }
>     res, err = acquireResource()
>     defer func() {
>         if err == nil {
>             err = res.Close()
>         }
>     }()
>     err = abc1()
>     err = abc2()
>     err = abc3()
>     err = abc4()
> }
>
> Also, I'd like to make a general comment (not specific to this case). The
> *watch* command doesn't seem (to me) a bad idea. And it could be used for
> other purposes too (e.g. as the "watch expression" feature in debuggers or
> for logging---yeah we don't really need it...).
>
> For instance:
>
> func calculations() {
>     x := 100.0
>     watch x < 0 {
>         fmt.Printf("hey, x is negative (%d)\n", x)
>         fmt.Printf("...no worries...\n")
>     }
>     x = compute(1,2,3)
>     x = compute(3,2,1)
>     x = compute(1,3,2)
> }
>
> It's of course NOT needed at all. Above, we can do the same thing in a
> different (probably better) way.
>
> In fact, *Go is perfect the way it is* and doesn't need any change at all!
>
> Also, the mechanics (implementation) of *watch* may be "impossible", "too
> hard", "confusing" or at least "inefficient"---I don't know (no idea...).
>
> With an opportunity to work on the Go language implementation, I would
> rather spend some time tweaking things to be faster...
>
> Cheers!
> Dorival
>
> On Wednesday, September 6, 2017 at 1:11:36 AM UTC+10, eko...@gmail.com
> wrote:
>
>> I've been doing something like this for long chains where "handle error"
>> is the same:
>>
>> func something() (x int, err error) {
>>     defer func() {
>>         if err != nil {
>>             // handle error
>>         }
>>     }()
>>     res, err = acquireResource()
>>     if err == nil {
>>         defer func() {
>>             if e := res.Close(); err == nil {
>>                 err = e
>>             }
>>         }()
>>         err = abc1()
>>     }
>>     if err == nil {
>>         err = abc2()
>>     }
>>     if err == nil {
>>         err = abc3()
>>     }
>>     if err == nil {
>>         err = abc4()
>>     }
>> }
>>
>> How would watch interact with defer?
>>
>> On Monday, September 4, 2017 at 8:27:20 PM UTC+2,
>> marti...@programmfabrik.de wrote:
>>>
>>> Hi guys,
>>>
>>> at first I though I really like the idea of how Go deals with error
>>> management and handling, but the more Go code I look at or try to program,
>>> the more I get scared about checking errors every second line in every
>>> given block of code.
>>>
>>> Take a look at this example here from "Build Web Application with
>>> Golang":
>>>
>>> // insert
>>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>>> created) values(?,?,?)")
>>> if err != nil {
>>>   // handle error
>>> }
>>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>>> if err != nil {
>>>   // handle error
>>> }
>>> id, err := res.LastInsertId()
>>> if err != nil {
>>>   // handle error
>>> }
>>> fmt.Println(id)
>>> // update
>>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>>> if err != nil {
>>>   // handle error
>>> }
>>> res, err = stmt.Exec("astaxieupdate", id)
>>> if err != nil {
>>>   // handle error
>>> }
>>> affect, err := res.RowsAffected()
>>> if err != nil {
>>>   // handle error
>>> }
>>>
>>>
>>> Seriously? And yes, I have read https://blog.golang.org/e
>>> rrors-are-values...
>>>
>>> The best case reduction I found is:
>>>
>>> ...
>>> res, err = stmt.Exec("astaxieupdate", id)
>>> checkError(err)
>>> ...
>>>
>>> Still, I need this after each line of calling a function which may
>>> return an error.
>>>
>>> I bet this is not pleasant to do in larger code bases and it also takes
>>> away focus from what is actually happening.
>>>
>>> 50-80% of all lines of code in my example deal with error handling?
>>>
>>> This is not good. Seriously.
>>>
>>> And don't get me wrong, there is a lot of things I really like, love and
>>> adore about Go, but catching errors needs an improved syntax!
>>>
>>> And I am not proposing try...catch here.
>>>
>>> How about introducing a new piece of syntax
>>>
>>> "watch if  .... "
>>>
>>> which tells the compiler to watch out for changes in a given SimpleStmt
>>>
>>> The same code as above would look like this:
>>>
>>> var err Error
>>>
>>> watch if err != nil {
>>>   // handle error(s)
>>> }
>>>
>>> // insert
>>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname,
>>> created) values(?,?,?)")
>>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>>> id, err := res.LastInsertId()
>>> fmt.Println(id)
>>>
>>> // update
>>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>>> res, err = stmt.Exec("astaxieupdate", id)
>>> affect, err := res.RowsAffected()
>>>
>>>
>>>    - The "watch if" would be executed after each assignment of any of
>>>    the variables used in SimpleStmt of the statement.
>>>    - Multiple "watch if" would be executed in order or appearance
>>>    - The "watch if" could be used like "defer..." inside functions
>>>    - The "watch if" would work in its full scope of the watched
>>>    variables
>>>
>>> I am not a language expert, so may be there is a saner way of expression
>>> what I want to achieve.
>>>
>>> But bottom line is, there should by an easier to read and write way to
>>> deal with errors in Go.
>>>
>>>
>>> Martin
>>>
>>>
>>>
>>>
>>>
>>> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Michael T. Jones
michael.jo...@gmail.com

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to