text: // Copyright 2017 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  // Package errd simplifies error and defer handling.
  //
  // Overview
  //
  // Package errd allows returning form a block of code without using the usual if
  // clauses, while properly intercepting errors and passing them to code called
  // at defer time.
  //
  // The following piece of idiomatic Go writes the contents of a reader to a file
  // on Google Cloud Storage:
  //
  //     func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
  //         client, err := storage.NewClient(ctx)
  //         if err != nil {
  //             return err
  //         }
  //         defer client.Close()
  //
  //         w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
  //         defer func() {
  //             if r := recover(); r != nil {
  //                 w.CloseWithError(fmt.Errorf("panic: %v", r))
  //                 panic(r)
  //             }
  //             if err != nil {
  //                 _ = w.CloseWithError(err)
  //             } else {
  //                 err = w.Close()
  //             }
  //         }
  //         _, err = io.Copy(w, r)
  //         return err
  //     }
  //
  // Google Cloud Storage allows files to be written atomically. This code
  // minimizes the chance of writing a bad file by aborting the write, using
  // CloseWithError, whenever any anomaly is encountered. This includes a
  // panic that could occur in the reader.
  //
  // Package errd aims to reduce bugs resulting from such subtleties by
  // making the default of having very strict error checking easy.
  // The following code achieves the same as the above:
  //
  //     func writeToGS(ctx context.Context, bucket, dst, src string, r io.Reader) error {
  //         return errd.Run(func(e *errd.E) {
  //             client, err := storage.NewClient(ctx)
  //             e.Must(err)
  //             e.Defer(client.Close, errd.Discard)
  //
  //             w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
  //             e.Defer(w.CloseWithError)
  //
  //             _, err = io.Copy(w, r)
  //             e.Must(err)
  //         })
  //     }
  //
  // Discard is an example of an error handler. Here it signals that we want
  // to ignore the error of the first Close.
  //
  //
  // Error Handlers
  //
  // In all of the code above we made the common faux pas of passing errors on
  // without decorating them. Package errd defines a Handler type to simplify the
  // task of decorating.
  //
  // Suppose we want to use github.com/pkg/errors to decorate errors. A simple
  // handler can be defined as:
  //
  //     type msg string
  //
  //     func (m msg) Handle(s errd.State, err error) error {
  //         return errors.WithMessage(err, string(m))
  //     }
  //
  // This handler can then be used as follows:
  //
  //     func writeToGS(ctx context.Context, bucket, dst, src string) error {
  //         return errd.Run(func(e *errd.E) {
  //             client, err := storage.NewClient(ctx)
  //             e.Must(err, msg("error opening client"))
  //             e.Defer(client.Close)
  //
  //             w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
  //             e.Defer(w.CloseWithError)
  //
  //             _, err = io.Copy(w, r)
  //             e.Must(err, msg("error copying contents"))
  //         })
  //     }
  //
  // The storage package used in this example defines the errors that are
  // typically a result of user error. It would be possible to write a more
  // generic storage writer that will add additional clarification when possible.
  // Using such a handler as a default handler would look like:
  //
  //     var ecGS = errd.WithDefault(storageHandler)
  //
  //     func writeToGS(ctx context.Context, bucket, dst, src string) error {
  //         return ecGS.Run(func(e *errd.E) {
  //             client, err := storage.NewClient(ctx)
  //             e.Must(err)
  //             e.Defer(client.Close)
  //             ...
  //         })
  //     }
  //
  // Setting up a global config with a default handler and using that everywhere
  // makes it easy to enforce decorating errors. Error handlers can also be used
  // to pass up HTTP error codes, log errors, attach metrics, etc.
  //
  //
  // Returning Values
  //
  // A function that is passed to Run does have any return values, not even an
  // error. Users are supposed to set return values in the outer scope, for
  // example by using named return variables.
  //
  //    func foo() (name string, err error) {
  //        return name, Run(func(e *errd.E) {
  //            //   Some fun code here.
  //            //   Set name at the end.
  //            name = "bar"
  //        })
  //    }
  //
  // If name is only set at the end, any error will force an early return from Run
  // and leave name empty. Otherwise, name will be set and err will be nil.
  package errd
  
  // TODO
  //
  // - Examples
  //
  // - Add semantic versioning.
  //
  // Consider these API changes:
  //
  // - Option to chose error, where a newly encountered error may be returned
  //   instead of a previously selected one. Could be an option Replace in State.
  // - Allow functions of signature func(), func(error), func() error, and
  //   func(error) error, to be passed to Defer.
  //
  // For v2, if performance allows::
  // - make E an interface: this allows injecting with test simulator.
  //   Would be great for such functionality. Go docs will not look as nice,
  //   though.
  