2
2
mirror of https://github.com/octoleo/restic.git synced 2024-12-01 17:23:57 +00:00

Always use errors.Cause() for testing error values

This commit is contained in:
Alexander Neumann 2016-08-29 19:18:57 +02:00
parent c55b6ee544
commit b06845c545
24 changed files with 70 additions and 44 deletions

View File

@ -13,6 +13,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
@ -222,7 +224,7 @@ func (cmd CmdBackup) newArchiveStdinProgress() *restic.Progress {
func filterExisting(items []string) (result []string, err error) { func filterExisting(items []string) (result []string, err error) {
for _, item := range items { for _, item := range items {
_, err := fs.Lstat(item) _, err := fs.Lstat(item)
if err != nil && os.IsNotExist(err) { if err != nil && os.IsNotExist(errors.Cause(err)) {
continue continue
} }

View File

@ -7,6 +7,8 @@ import (
"os" "os"
"restic" "restic"
"github.com/pkg/errors"
resticfs "restic/fs" resticfs "restic/fs"
"restic/fuse" "restic/fuse"
@ -56,7 +58,7 @@ func (cmd CmdMount) Execute(args []string) error {
} }
mountpoint := args[0] mountpoint := args[0]
if _, err := resticfs.Stat(mountpoint); os.IsNotExist(err) { if _, err := resticfs.Stat(mountpoint); os.IsNotExist(errors.Cause(err)) {
cmd.global.Verbosef("Mountpoint %s doesn't exist, creating it\n", mountpoint) cmd.global.Verbosef("Mountpoint %s doesn't exist, creating it\n", mountpoint)
err = resticfs.Mkdir(mountpoint, os.ModeDir|0700) err = resticfs.Mkdir(mountpoint, os.ModeDir|0700)
if err != nil { if err != nil {

View File

@ -19,6 +19,7 @@ import (
"restic/repository" "restic/repository"
"github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
@ -183,7 +184,7 @@ func readPassword(in io.Reader) (password string, err error) {
n, err := io.ReadFull(in, buf) n, err := io.ReadFull(in, buf)
buf = buf[:n] buf = buf[:n]
if err != nil && err != io.ErrUnexpectedEOF { if err != nil && errors.Cause(err) != io.ErrUnexpectedEOF {
return "", err return "", err
} }

View File

@ -10,6 +10,8 @@ import (
"testing" "testing"
"time" "time"
"github.com/pkg/errors"
"restic" "restic"
"restic/backend" "restic/backend"
"restic/repository" "restic/repository"
@ -125,7 +127,7 @@ func TestMount(t *testing.T) {
datafile := filepath.Join("testdata", "backup-data.tar.gz") datafile := filepath.Join("testdata", "backup-data.tar.gz")
fd, err := os.Open(datafile) fd, err := os.Open(datafile)
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
t.Skipf("unable to find data file %q, skipping", datafile) t.Skipf("unable to find data file %q, skipping", datafile)
return return
} }

View File

@ -16,6 +16,8 @@ import (
"testing" "testing"
"time" "time"
"github.com/pkg/errors"
"restic/backend" "restic/backend"
"restic/debug" "restic/debug"
"restic/filter" "restic/filter"
@ -142,7 +144,7 @@ func TestBackup(t *testing.T) {
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
datafile := filepath.Join("testdata", "backup-data.tar.gz") datafile := filepath.Join("testdata", "backup-data.tar.gz")
fd, err := os.Open(datafile) fd, err := os.Open(datafile)
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
t.Skipf("unable to find data file %q, skipping", datafile) t.Skipf("unable to find data file %q, skipping", datafile)
return return
} }
@ -204,7 +206,7 @@ func TestBackupNonExistingFile(t *testing.T) {
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
datafile := filepath.Join("testdata", "backup-data.tar.gz") datafile := filepath.Join("testdata", "backup-data.tar.gz")
fd, err := os.Open(datafile) fd, err := os.Open(datafile)
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
t.Skipf("unable to find data file %q, skipping", datafile) t.Skipf("unable to find data file %q, skipping", datafile)
return return
} }
@ -232,7 +234,7 @@ func TestBackupMissingFile1(t *testing.T) {
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
datafile := filepath.Join("testdata", "backup-data.tar.gz") datafile := filepath.Join("testdata", "backup-data.tar.gz")
fd, err := os.Open(datafile) fd, err := os.Open(datafile)
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
t.Skipf("unable to find data file %q, skipping", datafile) t.Skipf("unable to find data file %q, skipping", datafile)
return return
} }
@ -270,7 +272,7 @@ func TestBackupMissingFile2(t *testing.T) {
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
datafile := filepath.Join("testdata", "backup-data.tar.gz") datafile := filepath.Join("testdata", "backup-data.tar.gz")
fd, err := os.Open(datafile) fd, err := os.Open(datafile)
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
t.Skipf("unable to find data file %q, skipping", datafile) t.Skipf("unable to find data file %q, skipping", datafile)
return return
} }
@ -308,7 +310,7 @@ func TestBackupDirectoryError(t *testing.T) {
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
datafile := filepath.Join("testdata", "backup-data.tar.gz") datafile := filepath.Join("testdata", "backup-data.tar.gz")
fd, err := os.Open(datafile) fd, err := os.Open(datafile)
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
t.Skipf("unable to find data file %q, skipping", datafile) t.Skipf("unable to find data file %q, skipping", datafile)
return return
} }
@ -625,7 +627,7 @@ func TestRestoreFilter(t *testing.T) {
if ok, _ := filter.Match(pat, filepath.Base(test.name)); !ok { if ok, _ := filter.Match(pat, filepath.Base(test.name)); !ok {
OK(t, err) OK(t, err)
} else { } else {
Assert(t, os.IsNotExist(err), Assert(t, os.IsNotExist(errors.Cause(err)),
"expected %v to not exist in restore step %v, but it exists, err %v", test.name, i+1, err) "expected %v to not exist in restore step %v, but it exists, err %v", test.name, i+1, err)
} }
} }
@ -673,15 +675,15 @@ func TestRestoreLatest(t *testing.T) {
cmdRestoreLatest(t, global, filepath.Join(env.base, "restore1"), []string{filepath.Dir(p1)}, "") cmdRestoreLatest(t, global, filepath.Join(env.base, "restore1"), []string{filepath.Dir(p1)}, "")
OK(t, testFileSize(p1rAbs, int64(102))) OK(t, testFileSize(p1rAbs, int64(102)))
if _, err := os.Stat(p2rAbs); os.IsNotExist(err) { if _, err := os.Stat(p2rAbs); os.IsNotExist(errors.Cause(err)) {
Assert(t, os.IsNotExist(err), Assert(t, os.IsNotExist(errors.Cause(err)),
"expected %v to not exist in restore, but it exists, err %v", p2rAbs, err) "expected %v to not exist in restore, but it exists, err %v", p2rAbs, err)
} }
cmdRestoreLatest(t, global, filepath.Join(env.base, "restore2"), []string{filepath.Dir(p2)}, "") cmdRestoreLatest(t, global, filepath.Join(env.base, "restore2"), []string{filepath.Dir(p2)}, "")
OK(t, testFileSize(p2rAbs, int64(103))) OK(t, testFileSize(p2rAbs, int64(103)))
if _, err := os.Stat(p1rAbs); os.IsNotExist(err) { if _, err := os.Stat(p1rAbs); os.IsNotExist(errors.Cause(err)) {
Assert(t, os.IsNotExist(err), Assert(t, os.IsNotExist(errors.Cause(err)),
"expected %v to not exist in restore, but it exists, err %v", p1rAbs, err) "expected %v to not exist in restore, but it exists, err %v", p1rAbs, err)
} }

View File

@ -9,6 +9,7 @@ import (
"restic/repository" "restic/repository"
"time" "time"
"github.com/pkg/errors"
"github.com/restic/chunker" "github.com/restic/chunker"
) )
@ -48,7 +49,7 @@ func ArchiveReader(repo *repository.Repository, p *Progress, rd io.Reader, name
for { for {
chunk, err := chnker.Next(getBuf()) chunk, err := chnker.Next(getBuf())
if err == io.EOF { if errors.Cause(err) == io.EOF {
break break
} }

View File

@ -225,7 +225,7 @@ func (arch *Archiver) SaveFile(p *Progress, node *Node) error {
for { for {
chunk, err := chnker.Next(getBuf()) chunk, err := chnker.Next(getBuf())
if err == io.EOF { if errors.Cause(err) == io.EOF {
break break
} }

View File

@ -14,6 +14,7 @@ import (
"restic/repository" "restic/repository"
. "restic/test" . "restic/test"
"github.com/pkg/errors"
"github.com/restic/chunker" "github.com/restic/chunker"
) )
@ -31,7 +32,7 @@ func benchmarkChunkEncrypt(b testing.TB, buf, buf2 []byte, rd Rdr, key *crypto.K
for { for {
chunk, err := ch.Next(buf) chunk, err := ch.Next(buf)
if err == io.EOF { if errors.Cause(err) == io.EOF {
break break
} }
@ -69,7 +70,7 @@ func benchmarkChunkEncryptP(b *testing.PB, buf []byte, rd Rdr, key *crypto.Key)
for { for {
chunk, err := ch.Next(buf) chunk, err := ch.Next(buf)
if err == io.EOF { if errors.Cause(err) == io.EOF {
break break
} }
@ -292,7 +293,7 @@ func getRandomData(seed int, size int) []chunker.Chunk {
for { for {
c, err := chunker.Next(nil) c, err := chunker.Next(nil)
if err == io.EOF { if errors.Cause(err) == io.EOF {
break break
} }
chunks = append(chunks, c) chunks = append(chunks, c)

View File

@ -232,7 +232,7 @@ func (b *Local) Test(t backend.Type, name string) (bool, error) {
debug.Log("backend.local.Test", "Test %v %v", t, name) debug.Log("backend.local.Test", "Test %v %v", t, name)
_, err := fs.Stat(filename(b.p, t, name)) _, err := fs.Stat(filename(b.p, t, name))
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
return false, nil return false, nil
} }
return false, err return false, err

View File

@ -125,7 +125,7 @@ func (be s3) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
// return an error if the offset is beyond the end of the file // return an error if the offset is beyond the end of the file
if off > info.Size { if off > info.Size {
return 0, io.EOF return 0, errors.Wrap(io.EOF, "")
} }
var nextError error var nextError error
@ -141,7 +141,7 @@ func (be s3) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
} }
n, err = obj.ReadAt(p, off) n, err = obj.ReadAt(p, off)
if int64(n) == info.Size-off && err == io.EOF { if int64(n) == info.Size-off && errors.Cause(err) == io.EOF {
err = nil err = nil
} }

View File

@ -429,7 +429,7 @@ func (r *SFTP) Test(t backend.Type, name string) (bool, error) {
} }
_, err := r.c.Lstat(r.filename(t, name)) _, err := r.c.Lstat(r.filename(t, name))
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
return false, nil return false, nil
} }

View File

@ -6,6 +6,8 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/pkg/errors"
"restic/backend" "restic/backend"
"restic/backend/sftp" "restic/backend/sftp"
"restic/backend/test" "restic/backend/test"
@ -37,7 +39,7 @@ func init() {
for _, dir := range strings.Split(TestSFTPPath, ":") { for _, dir := range strings.Split(TestSFTPPath, ":") {
testpath := filepath.Join(dir, "sftp-server") testpath := filepath.Join(dir, "sftp-server")
_, err := os.Stat(testpath) _, err := os.Stat(testpath)
if !os.IsNotExist(err) { if !os.IsNotExist(errors.Cause(err)) {
sftpserver = testpath sftpserver = testpath
break break
} }

View File

@ -10,6 +10,8 @@ import (
"sort" "sort"
"testing" "testing"
"github.com/pkg/errors"
"restic/backend" "restic/backend"
. "restic/test" . "restic/test"
) )
@ -223,7 +225,7 @@ func TestLoad(t testing.TB) {
// if we requested data beyond the end of the file, require // if we requested data beyond the end of the file, require
// ErrUnexpectedEOF error // ErrUnexpectedEOF error
if l > len(d) { if l > len(d) {
if err != io.ErrUnexpectedEOF { if errors.Cause(err) != io.ErrUnexpectedEOF {
t.Errorf("Load(%d, %d) did not return io.ErrUnexpectedEOF", len(buf), int64(o)) t.Errorf("Load(%d, %d) did not return io.ErrUnexpectedEOF", len(buf), int64(o))
} }
err = nil err = nil
@ -270,7 +272,7 @@ func TestLoad(t testing.TB) {
// if we requested data beyond the end of the file, require // if we requested data beyond the end of the file, require
// ErrUnexpectedEOF error // ErrUnexpectedEOF error
if l > len(d) { if l > len(d) {
if err != io.ErrUnexpectedEOF { if errors.Cause(err) != io.ErrUnexpectedEOF {
t.Errorf("Load(%d, %d) did not return io.ErrUnexpectedEOF", len(buf), int64(o)) t.Errorf("Load(%d, %d) did not return io.ErrUnexpectedEOF", len(buf), int64(o))
continue continue
} }
@ -303,7 +305,7 @@ func TestLoad(t testing.TB) {
t.Errorf("wrong length for larger buffer returned, want %d, got %d", length, n) t.Errorf("wrong length for larger buffer returned, want %d, got %d", length, n)
} }
if err != io.ErrUnexpectedEOF { if errors.Cause(err) != io.ErrUnexpectedEOF {
t.Errorf("wrong error returned for larger buffer: want io.ErrUnexpectedEOF, got %#v", err) t.Errorf("wrong error returned for larger buffer: want io.ErrUnexpectedEOF, got %#v", err)
} }
@ -337,7 +339,7 @@ func TestLoadNegativeOffset(t testing.TB) {
// if we requested data beyond the end of the file, require // if we requested data beyond the end of the file, require
// ErrUnexpectedEOF error // ErrUnexpectedEOF error
if len(buf) > -o { if len(buf) > -o {
if err != io.ErrUnexpectedEOF { if errors.Cause(err) != io.ErrUnexpectedEOF {
t.Errorf("Load(%d, %d) did not return io.ErrUnexpectedEOF", len(buf), o) t.Errorf("Load(%d, %d) did not return io.ErrUnexpectedEOF", len(buf), o)
continue continue
} }

View File

@ -1,6 +1,10 @@
package backend package backend
import "io" import (
"io"
"github.com/pkg/errors"
)
// LoadAll reads all data stored in the backend for the handle. The buffer buf // LoadAll reads all data stored in the backend for the handle. The buffer buf
// is resized to accomodate all data in the blob. Errors returned by be.Load() // is resized to accomodate all data in the blob. Errors returned by be.Load()
@ -17,7 +21,7 @@ func LoadAll(be Backend, h Handle, buf []byte) ([]byte, error) {
} }
n, err := be.Load(h, buf, 0) n, err := be.Load(h, buf, 0)
if err == io.ErrUnexpectedEOF { if errors.Cause(err) == io.ErrUnexpectedEOF {
err = nil err = nil
} }
buf = buf[:n] buf = buf[:n]

View File

@ -48,7 +48,7 @@ func (c *Cache) Has(t backend.Type, subtype string, id backend.ID) (bool, error)
defer fd.Close() defer fd.Close()
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
debug.Log("Cache.Has", "test for file %v: not cached", filename) debug.Log("Cache.Has", "test for file %v: not cached", filename)
return false, nil return false, nil
} }
@ -106,7 +106,7 @@ func (c *Cache) purge(t backend.Type, subtype string, id backend.ID) error {
err = fs.Remove(filename) err = fs.Remove(filename)
debug.Log("Cache.purge", "Remove file %v: %v", filename, err) debug.Log("Cache.purge", "Remove file %v: %v", filename, err)
if err != nil && os.IsNotExist(err) { if err != nil && os.IsNotExist(errors.Cause(err)) {
return nil return nil
} }
@ -160,7 +160,7 @@ func (c *Cache) list(t backend.Type) ([]cacheEntry, error) {
fd, err := fs.Open(dir) fd, err := fs.Open(dir)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
return []cacheEntry{}, nil return []cacheEntry{}, nil
} }
return nil, err return nil, err
@ -231,7 +231,7 @@ func getWindowsCacheDir() (string, error) {
cachedir = filepath.Join(cachedir, "restic") cachedir = filepath.Join(cachedir, "restic")
fi, err := fs.Stat(cachedir) fi, err := fs.Stat(cachedir)
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
err = fs.MkdirAll(cachedir, 0700) err = fs.MkdirAll(cachedir, 0700)
if err != nil { if err != nil {
return "", err return "", err
@ -268,7 +268,7 @@ func getXDGCacheDir() (string, error) {
} }
fi, err := fs.Stat(cachedir) fi, err := fs.Stat(cachedir)
if os.IsNotExist(err) { if os.IsNotExist(errors.Cause(err)) {
err = fs.MkdirAll(cachedir, 0700) err = fs.MkdirAll(cachedir, 0700)
if err != nil { if err != nil {
return "", err return "", err

View File

@ -85,7 +85,7 @@ func (c *Checker) LoadIndex() (hints []error, errs []error) {
worker := func(id backend.ID, done <-chan struct{}) error { worker := func(id backend.ID, done <-chan struct{}) error {
debug.Log("LoadIndex", "worker got index %v", id) debug.Log("LoadIndex", "worker got index %v", id)
idx, err := repository.LoadIndexWithDecoder(c.repo, id, repository.DecodeIndex) idx, err := repository.LoadIndexWithDecoder(c.repo, id, repository.DecodeIndex)
if err == repository.ErrOldIndexFormat { if errors.Cause(err) == repository.ErrOldIndexFormat {
debug.Log("LoadIndex", "index %v has old format", id.Str()) debug.Log("LoadIndex", "index %v has old format", id.Str())
hints = append(hints, ErrOldIndexFormat{id}) hints = append(hints, ErrOldIndexFormat{id})

View File

@ -14,6 +14,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/pkg/errors"
) )
type process struct { type process struct {
@ -59,7 +61,7 @@ func initDebugLogger() {
} }
} }
if err != nil && os.IsNotExist(err) { if err != nil && os.IsNotExist(errors.Cause(err)) {
f, err = fs.OpenFile(debugfile, os.O_WRONLY|os.O_CREATE, 0600) f, err = fs.OpenFile(debugfile, os.O_WRONLY|os.O_CREATE, 0600)
} }

View File

@ -6,13 +6,15 @@ import (
"os" "os"
"syscall" "syscall"
"github.com/pkg/errors"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
// Open opens a file for reading, without updating the atime and without caching data on read. // Open opens a file for reading, without updating the atime and without caching data on read.
func Open(name string) (File, error) { func Open(name string) (File, error) {
file, err := os.OpenFile(name, os.O_RDONLY|syscall.O_NOATIME, 0) file, err := os.OpenFile(name, os.O_RDONLY|syscall.O_NOATIME, 0)
if os.IsPermission(err) { if os.IsPermission(errors.Cause(err)) {
file, err = os.OpenFile(name, os.O_RDONLY, 0) file, err = os.OpenFile(name, os.O_RDONLY, 0)
} }
return &nonCachingFile{File: file}, err return &nonCachingFile{File: file}, err

View File

@ -296,7 +296,7 @@ func List(k *crypto.Key, rd io.ReaderAt, size int64) (entries []Blob, err error)
for { for {
e := headerEntry{} e := headerEntry{}
err = binary.Read(hdrRd, binary.LittleEndian, &e) err = binary.Read(hdrRd, binary.LittleEndian, &e)
if err == io.EOF { if errors.Cause(err) == io.EOF {
break break
} }

View File

@ -126,7 +126,7 @@ func SearchKey(s *Repository, password string, maxKeys int) (*Key, error) {
debug.Log("SearchKey", "key %v returned error %v", name[:12], err) debug.Log("SearchKey", "key %v returned error %v", name[:12], err)
// ErrUnauthenticated means the password is wrong, try the next key // ErrUnauthenticated means the password is wrong, try the next key
if err == crypto.ErrUnauthenticated { if errors.Cause(err) == crypto.ErrUnauthenticated {
continue continue
} }

View File

@ -7,6 +7,8 @@ import (
"restic/crypto" "restic/crypto"
"restic/debug" "restic/debug"
"restic/pack" "restic/pack"
"github.com/pkg/errors"
) )
// Repack takes a list of packs together with a list of blobs contained in // Repack takes a list of packs together with a list of blobs contained in
@ -22,7 +24,7 @@ func Repack(repo *Repository, packs backend.IDSet, keepBlobs pack.BlobSet) (err
h := backend.Handle{Type: backend.Data, Name: packID.String()} h := backend.Handle{Type: backend.Data, Name: packID.String()}
l, err := repo.Backend().Load(h, buf[:cap(buf)], 0) l, err := repo.Backend().Load(h, buf[:cap(buf)], 0)
if err == io.ErrUnexpectedEOF { if errors.Cause(err) == io.ErrUnexpectedEOF {
err = nil err = nil
buf = buf[:l] buf = buf[:l]
} }

View File

@ -403,7 +403,7 @@ func LoadIndex(repo *Repository, id backend.ID) (*Index, error) {
return idx, nil return idx, nil
} }
if err == ErrOldIndexFormat { if errors.Cause(err) == ErrOldIndexFormat {
fmt.Fprintf(os.Stderr, "index %v has old format\n", id.Str()) fmt.Fprintf(os.Stderr, "index %v has old format\n", id.Str())
return LoadIndexWithDecoder(repo, id, DecodeOldIndex) return LoadIndexWithDecoder(repo, id, DecodeOldIndex)
} }

View File

@ -95,7 +95,7 @@ func (res *Restorer) restoreNodeTo(node *Node, dir string, dst string) error {
} }
// Did it fail because of ENOENT? // Did it fail because of ENOENT?
if err != nil && os.IsNotExist(err) { if err != nil && os.IsNotExist(errors.Cause(err)) {
debug.Log("Restorer.restoreNodeTo", "create intermediate paths") debug.Log("Restorer.restoreNodeTo", "create intermediate paths")
// Create parent directories and retry // Create parent directories and retry

View File

@ -11,6 +11,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/pkg/errors"
"github.com/restic/chunker" "github.com/restic/chunker"
) )
@ -34,7 +35,7 @@ func (fs fakeFileSystem) saveFile(rd io.Reader) (blobs backend.IDs) {
for { for {
chunk, err := ch.Next(getBuf()) chunk, err := ch.Next(getBuf())
if err == io.EOF { if errors.Cause(err) == io.EOF {
break break
} }