Use multierror in more places

While I'm here, do not allocate multierror.Error, multierror.Append will
do it when needed.
This commit is contained in:
Julien Laffaye 2022-03-01 13:14:25 -05:00
parent 212daf295f
commit a81b090061

100
ftp.go
View File

@ -8,7 +8,6 @@ import (
"context" "context"
"crypto/tls" "crypto/tls"
"errors" "errors"
"fmt"
"io" "io"
"net" "net"
"net/textproto" "net/textproto"
@ -592,21 +591,23 @@ func (c *ServerConn) NameList(path string) (entries []string, err error) {
return nil, err return nil, err
} }
var errs *multierror.Error
r := &Response{conn: conn, c: c} r := &Response{conn: conn, c: c}
defer func() {
errClose := r.Close()
if err == nil {
err = errClose
}
}()
scanner := bufio.NewScanner(c.options.wrapStream(r)) scanner := bufio.NewScanner(c.options.wrapStream(r))
for scanner.Scan() { for scanner.Scan() {
entries = append(entries, scanner.Text()) entries = append(entries, scanner.Text())
} }
err = scanner.Err() if err := scanner.Err(); err != nil {
return entries, err errs = multierror.Append(errs, err)
}
if err := r.Close(); err != nil {
errs = multierror.Append(errs, err)
}
return entries, errs.ErrorOrNil()
} }
// List issues a LIST FTP command. // List issues a LIST FTP command.
@ -631,25 +632,29 @@ func (c *ServerConn) List(path string) (entries []*Entry, err error) {
return nil, err return nil, err
} }
var errs *multierror.Error
r := &Response{conn: conn, c: c} r := &Response{conn: conn, c: c}
defer func() {
errClose := r.Close()
if err == nil {
err = errClose
}
}()
scanner := bufio.NewScanner(c.options.wrapStream(r)) scanner := bufio.NewScanner(c.options.wrapStream(r))
now := time.Now() now := time.Now()
for scanner.Scan() { for scanner.Scan() {
entry, errParse := parser(scanner.Text(), now, c.options.location) entry, errParse := parser(scanner.Text(), now, c.options.location)
if errParse == nil { if errParse != nil {
errs = multierror.Append(errs, errParse)
} else {
entries = append(entries, entry) entries = append(entries, entry)
} }
} }
err = scanner.Err() if err := scanner.Err(); err != nil {
return entries, err errs = multierror.Append(errs, err)
}
if err := r.Close(); err != nil {
errs = multierror.Append(errs, err)
}
return entries, errs.ErrorOrNil()
} }
// IsTimePreciseInList returns true if client and server support the MLSD // IsTimePreciseInList returns true if client and server support the MLSD
@ -802,22 +807,22 @@ func (c *ServerConn) StorFrom(path string, r io.Reader, offset uint64) error {
return err return err
} }
errs := &multierror.Error{} var errs *multierror.Error
// if the upload fails we still need to try to read the server // if the upload fails we still need to try to read the server
// response otherwise if the failure is not due to a connection problem, // response otherwise if the failure is not due to a connection problem,
// for example the server denied the upload for quota limits, we miss // for example the server denied the upload for quota limits, we miss
// the response and we cannot use the connection to send other commands. // the response and we cannot use the connection to send other commands.
if _, err := io.Copy(conn, r); err != nil { if _, err := io.Copy(conn, r); err != nil {
multierror.Append(errs, err) errs = multierror.Append(errs, err)
} }
if err := conn.Close(); err != nil { if err := conn.Close(); err != nil {
multierror.Append(errs, err) errs = multierror.Append(errs, err)
} }
if err := c.checkDataShut(); err != nil { if err := c.checkDataShut(); err != nil {
multierror.Append(errs, err) errs = multierror.Append(errs, err)
} }
return errs.ErrorOrNil() return errs.ErrorOrNil()
@ -834,20 +839,21 @@ func (c *ServerConn) Append(path string, r io.Reader) error {
return err return err
} }
// see the comment for StorFrom above var errs *multierror.Error
_, err = io.Copy(conn, r)
errClose := conn.Close()
respErr := c.checkDataShut() if _, err := io.Copy(conn, r); err != nil {
if respErr != nil { errs = multierror.Append(errs, err)
err = respErr
} }
if err == nil { if err := conn.Close(); err != nil {
err = errClose errs = multierror.Append(errs, err)
} }
return err if err := c.checkDataShut(); err != nil {
errs = multierror.Append(errs, err)
}
return errs.ErrorOrNil()
} }
// Rename renames a file on the remote FTP server. // Rename renames a file on the remote FTP server.
@ -954,17 +960,17 @@ func (c *ServerConn) Logout() error {
// Quit issues a QUIT FTP command to properly close the connection from the // Quit issues a QUIT FTP command to properly close the connection from the
// remote FTP server. // remote FTP server.
func (c *ServerConn) Quit() error { func (c *ServerConn) Quit() error {
_, errQuit := c.conn.Cmd("QUIT") var errs *multierror.Error
err := c.conn.Close()
if errQuit != nil { if _, err := c.conn.Cmd("QUIT"); err != nil {
if err != nil { errs = multierror.Append(errs, err)
return fmt.Errorf("error while quitting: %s: %w", errQuit, err)
}
return errQuit
} }
return err if err := c.conn.Close(); err != nil {
errs = multierror.Append(errs, err)
}
return errs.ErrorOrNil()
} }
// Read implements the io.Reader interface on a FTP data connection. // Read implements the io.Reader interface on a FTP data connection.
@ -978,13 +984,19 @@ func (r *Response) Close() error {
if r.closed { if r.closed {
return nil return nil
} }
err := r.conn.Close()
err2 := r.c.checkDataShut() var errs *multierror.Error
if err2 != nil {
err = err2 if err := r.conn.Close(); err != nil {
errs = multierror.Append(errs, err)
} }
if err := r.c.checkDataShut(); err != nil {
errs = multierror.Append(errs, err)
}
r.closed = true r.closed = true
return err return errs.ErrorOrNil()
} }
// SetDeadline sets the deadlines associated with the connection. // SetDeadline sets the deadlines associated with the connection.