
Go 2.0 Error Handling Requirements - networkimprov
https://gist.github.com/networkimprov/961c9caa2631ad3b95413f7d44a2c98a
======
tgsovlerkhgsel
No word about adding proper stack traces by default?

Currently, your best bet of finding where an error was actually generated, if
it is returned a few times before finally being logged/returned to an RPC
client, is searching for fragments of the error string and hoping that a) the
part that you searched for is part of the literal and not dynamically built b)
it is unique c) you can guess the call path that led to this error.

Of course, in a perfect world, all error messages would be so descriptive that
you could immediately find the issue just by reading the error message, but
unfortunately, ideals and ideology rarely create solutions that work well in
the real world.

~~~
ben_jones
A nifty code snippet I use for this:

    
    
      // ErrLine returns an error formatted to include the line 
      // number of where it occurred (presumably with a performance penalty)
      func ErrLine(err error) error {
        if err != nil {
          // notice that we're using 1, so it will actually log the where
          // the error happened, 0 = this function, we don't want that.
          pc, fn, line, _ := runtime.Caller(1)
          err = fmt.Errorf("[error] in %s[%s:%d]: %s", 
          runtime.FuncForPC(pc).Name(), fn, line, err.Error())
    
        }
    
        return err
      }

~~~
stouset
Edit: I misread this comment. Apologies.

~~~
fierro
yes, why use a function

------
maddyboo
I scanned through almost all of the posts on the feedback wiki, and this was
the only one I saw which addresses handling recoverable errors.

Recoverable errors are definitely a thing, but the original error handling
proposal forces the handler chain to eventually return, making it impossible
to continue function execution [1]:

> If the enclosing function has result parameters, it is a compile-time error
> if at the point of any check expression none of the handlers in scope is a
> terminating statement. Note that the default handler ends in a terminating
> statement.

As suggested in section H of this post, I think `break` or a similar mechanism
inside handlers would be very useful.

[1]:
[https://go.googlesource.com/proposal/+/master/design/go2draf...](https://go.googlesource.com/proposal/+/master/design/go2draft-
error-handling.md#summary)

------
networkimprov
From the feedback wiki, it's clear that check/handle wasn't that well
received. These requirements might illuminate a viable path.

[https://github.com/golang/go/wiki/Go2ErrorHandlingFeedback](https://github.com/golang/go/wiki/Go2ErrorHandlingFeedback)

~~~
coder543
The discussions I saw on Reddit were strongly in favor of `check`, and the
link you provided seems to show a 50/50 split, so your summary surprises me.
People suggesting changes doesn't indicate that people oppose the idea, in my
opinion... it means they're interested in making sure the execution is good.

~~~
networkimprov
I don't see where the 50/50 split is. I didn't imply that the feedback
rejected any change to error handling.

Re 'check', more than half of the counter-proposals suggest various ways to
select a _named_ handler, which check cannot do.

~~~
coder543
> I don't see where the 50/50 split is.

There are 3 articles under "In support" and 3 articles under "Against". A
pretty literal 50/50 split.

~~~
networkimprov
Ah, indeed :-) But many of the counter-proposals offer very different
solutions than check/handle, so I'd count them as variations of "against".

------
codr4
Go's resistance to exceptions looks like Steve Jobs and his one button mouse
from here. It's not like renaming them to panic/recover fooled anyone outside
of the Pike reality distortion field. Sometimes unwinding the stack is exactly
what you want. Optional types are nice too, but that's more for things that
are intentionally missing. I have yet to see anything here that's an
improvement over just doing the obvious thing.

~~~
nicoburns
I'm not sure about that. Rust's use of a Result type instead of exceptions is
one of my favourite things about Rust. Before I'd used it, I'd not realised
how many reliability issues in other languages were caused by overlooked
exception cases.

Exceptions are great when you don't want to handle errors properly, but when
you do want robust error handling I find the "return a value" pattern much
better. Notably even C++ is looking into implementing this!

~~~
codr4
They are not overlooked, they are better handled further up the call stack.
And not having the option to forward them implicitly is a step back, not
forward. There's no way to make a programming language better by forcing users
to do anything, in many cases the user will have more experience than the
person implementing the language. A programming language is a tool, predicting
and dictating how the tool is to be used is missing the point.

~~~
qz_
I don't think forcing is the right word.. I've noticed that languages where
the "right way" is the path of least resistance the code quality stays high
even if a lot of people with varying levels of expertise contribute

~~~
maxscam
Well in my experience golang Is a long ways from this anyway ... It's a very
prescriptive language

