Hi, could you link this thread on the Feedback wiki page (probably in the 
Against section)?
https://github.com/golang/go/wiki/Go2ErrorHandlingFeedback

URL to this thread:
https://groups.google.com/d/topic/golang-nuts/1McP4_-oOpo/discussion

It seems clear that the Go team has resolved to add *something* to the 
language for error handling; they've heard a lot of complaints, over a long 
period. Also there's much more to error handling than what's contemplated 
in the draft design; see the Requirements section of the wiki.


On Monday, October 29, 2018 at 7:26:39 PM UTC-7, DrGo wrote:
>
> What I like about error handling in Go is that errors are just values. 
> Like any other values, they can be transparently stored, aggregated, passed 
> around and used, among other things, to explicitly change program flow. 
> That is why I am on the whole satisfied by Go 1's approach and a bit 
> concerned about many of the Go 2 proposals that provide specialized syntax 
> for handling errors.
>
> I know that checking for errors can lead to repetitive and verbose code. 
> My solution has been to refactor repetitive error handling logic into a 
> package-level function or a method on a receiver (or even a closure within 
> a method or function) depending on needs. For example in a parser package, 
> I might have a single method of the parser object that aggregates all 
> parsing errors and then provide an Err() method that can be used by caller 
> to check for and report any errors. This is the same approach used in 
> several occasions in the standard library and often results in clean and 
> idiomatic interfaces.
>
> This approach does not work as well in some scenarios, e.g., in routines 
> reading and writing files, where there are different types of errors 
> potentially returned at every step of opening, reading, creating, writing 
> and closing files and often requiring bailing out from the routine 
> hopefully with an informative error message. This often results in a code 
> like this:
>
> func CopyFile(src, dst string) error {
>  r, err := os.Open(src)
>  if err != nil {
>  return fmt.Errorf("copy %s %s: %v", src, dst, err)
>  }
>  defer r.Close()
>
>
>  w, err := os.Create(dst)
>  if err != nil {
>  return fmt.Errorf("copy %s %s: %v", src, dst, err)
>  }
>
>
>  if _, err := io.Copy(w, r); err != nil {
>  w.Close()
>  os.Remove(dst)
>  return fmt.Errorf("copy %s %s: %v", src, dst, err)
>  }
>
>
>  if err := w.Close(); err != nil {
>  os.Remove(dst)
>  return fmt.Errorf("copy %s %s: %v", src, dst, err)
>  }
>   return nil
> }
>
>
> source: Russ Cox. Error Handling — Problem Overview 
> https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md
>
> My approach currently is to try and reduce the clutter and repetitiveness 
> by creating one or more closures having the same return signature as the 
> enclosing function, so that I can return it if error is not null. That 
> results in the following code which for me represents a reasonable trade 
> off between avoiding repetitiveness and readability. 
>
>
>
> func CopyFile(dst, src string) error {
>  report:= func(err error) error {
>     return fmt.Errorf("failed to copy %s to %s: %v", src, dst, err)
>  }
>  closeAndReport:= func(w io.WriteCloser, err error) error {
>     w.Close()    //works because closing an already closed file is ok
>     os.Remove(dst) 
>     return report(err)
>  }
>  r, err := os.Open(src)
>  if err != nil {
>  return report(err)
>  }
>  defer r.Close()
>
>
>  w, err := os.Create(dst)
>  if err != nil {
>  return report(err)
>  }
>
>
>  if _, err := io.Copy(w, r); err != nil {
>  return closeAndReport(w, err)
>  }
>
>
>  if err := w.Close(); err != nil {
>  return closeAndReport(w, err)
>  }
>  return nil
> }
>
> Try it here https://play.golang.org/p/5INz2oW5c8p
>
> For me, the only needed change here is perhaps a mechanism to simplify the 
> if err!= nil { return myClosure()} bit. I guess this is what the proposed 
> "check" keyword in Russ's proposal is supposed to do. For example, 
>
> r, err := os.Open(src)
> if err != nil {
>   return report(err)
> }
>
>
>
> becomes
>
> r := check os.Open(src)
>
>
> As many have pointed out, the check keyword has several shortcomings the 
> most important for me are that:
> (1) it obscures the change in workflow and (2) it treats error values 
> differently than all other values.
>
> Overall, I do not think that the gain in brevity compensates for the loss 
> in code clarity (and for the addition of 2 new keywords). Perhaps I am 
> lacking in imagination, but I am finding it really hard to think of ways to 
> beat the exquisite balancing act that Go 1 achieves when it comes to 
> handling errors and exceptions. 
>
> What do  you think?
>
>

-- 
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to