1
0
mirror of https://github.com/golang/go synced 2024-11-13 17:20:22 -07:00

io: clarify Copy docs regarding error handling

"returns ... the first error" was misleading or at least confusing:
in case a Read results in an error with non-zero bytes read, and the
subsequent Write also results in an error, the error from Write is
returned, which is the second one (in the temporal dimension).

Fixes #9744

Change-Id: If8925a701e4fae820cd9df7446503403fc0785d4
Reviewed-on: https://go-review.googlesource.com/3686
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Péter Surányi 2015-02-02 21:37:52 +09:00 committed by Brad Fitzpatrick
parent 8ac129e530
commit a814c05eba
2 changed files with 31 additions and 2 deletions

View File

@ -337,7 +337,8 @@ func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
// Copy copies from src to dst until either EOF is reached
// on src or an error occurs. It returns the number of bytes
// copied and the first error encountered while copying, if any.
// copied and the error that prevented it from progressing
// further, if any.
//
// A successful Copy returns err == nil, not err == EOF.
// Because Copy is defined to read from src until EOF, it does

View File

@ -78,6 +78,34 @@ func TestCopyPriority(t *testing.T) {
}
}
type zeroErrReader struct {
err error
}
func (r zeroErrReader) Read(p []byte) (int, error) {
return copy(p, []byte{0}), r.err
}
type errWriter struct {
err error
}
func (w errWriter) Write([]byte) (int, error) {
return 0, w.err
}
// In case a Read results in an error with non-zero bytes read, and
// the subsequent Write also results in an error, the error from Write
// is returned, as it is the one that prevented progressing further.
func TestCopyReadErrWriteErr(t *testing.T) {
er, ew := errors.New("readError"), errors.New("writeError")
r, w := zeroErrReader{err: er}, errWriter{err: ew}
n, err := Copy(w, r)
if n != 0 || err != ew {
t.Errorf("Copy(zeroErrReader, errWriter) = %d, %v; want 0, writeError", n, err)
}
}
func TestCopyN(t *testing.T) {
rb := new(Buffer)
wb := new(Buffer)