Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rethinking Errors in Go

Rethinking Errors in Go

We're starting to think about Go 2. This talk addresses some of the current issues with handling errors in Go. We introduce a burner package that addresses these issues by introducing a unified model of error, defer, and panic. Although this package can simplify Go code today, we hope that experience with this package can help us understand how error handling can be improved at the language level.

Marcel van Lohuizen

November 06, 2017
Tweet

More Decks by Marcel van Lohuizen

Other Decks in Programming

Transcript

  1. r, err := os.Open(“foo.txt”) if err != nil { return

    fmt.Errorf(“oops: %v”, err) } defer r.Close()
  2. func writeToGS(c net.Context, bkt, dst string, r io.Reader) (err error)

    { 
 w := client.Bucket(bkt).Object(dst).NewWriter(c) defer w.CloseWithError(err) if _, err = io.Copy(w, r); err != nil { return fmt.Errorf(“oops: %v”, err)
 } return nil }
  3. func writeToGS(c net.Context, bkt, dst string, r io.Reader) (err error)

    { err = errPanicking w := client.Bucket(bkt).Object(dst).NewWriter(c) defer w.CloseWithError(err) if _, err = io.Copy(w, r); err != nil { return fmt.Errorf(“oops: %v”, err)
 } return err } var errPanicking = errors.New(“panicking”) handle panic FAIL
  4. func writeToGS(c net.Context, bkt, dst string, r io.Reader) (err error)

    { 
 w := client.Bucket(bkt).Object(dst).NewWriter(c) err = errPanicking defer func() { if err != nil { _ = w.CloseWithError(err) } else if err = w.Close(); err != nil { err = fmt.Errorf(“oh noes: %v”, err)
 } } if _, err = io.Copy(w, r); err != nil { return fmt.Errorf(“oops: %v”, err)
 } return err } return error from Close FAIL
  5. func writeToGS(c net.Context, bkt, dst string, r io.Reader) (err error)

    { w := client.Bucket(bkt).Object(dst).NewWriter(c) err = errPanicking defer func() { if err != nil { _ = w.CloseWithError(err) } else if err = w.Close(); err != nil { err = fmt.Errorf(“oh noes: %v”, err) } }() if _, err = io.Copy(w, r); err != nil { return fmt.Errorf(“oops: %v”, err) } return nil } var errPanicking = errors.New(“panicking”)
  6. func writeToGS(c net.Context, bkt, dst string, r io.Reader) (err error)

    { e := errc.Catch(&err) defer e.Handle()
 w := client.Bucket(bkt).Object(dst).NewWriter(c) e.Defer(w.CloseWithError, msg(“oh noes”)) _, err = io.Copy(w, r) e.Must(err, msg(“oh no”)) return nil }
  7. Try it out! Feedback Welcome! Marcel van Lohuizen, Go core

    Team github.com/mpvl/errc github.com/mpvl/errd @mpvl_