try harder to convert transfer errors in well-known error types

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2023-04-08 14:55:04 +02:00
parent f03f1b0156
commit 4294659785
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
7 changed files with 29 additions and 3 deletions

View file

@ -1675,7 +1675,8 @@ func (c *BaseConnection) GetGenericError(err error) error {
return sftp.ErrSSHFxFailure
default:
if err == ErrPermissionDenied || err == ErrNotExist || err == ErrOpUnsupported ||
err == ErrQuotaExceeded || err == vfs.ErrStorageSizeUnavailable || err == ErrShuttingDown {
err == ErrQuotaExceeded || err == ErrReadQuotaExceeded || err == vfs.ErrStorageSizeUnavailable ||
err == ErrShuttingDown {
return err
}
c.Log(logger.LevelError, "generic error: %+v", err)

View file

@ -211,6 +211,18 @@ func (t *BaseTransfer) SetCancelFn(cancelFn func()) {
t.cancelFn = cancelFn
}
// ConvertError accepts an error that occurs during a read or write and
// converts it into a more understandable form for the client if it is a
// well-known type of error
func (t *BaseTransfer) ConvertError(err error) error {
if t.Fs.IsNotExist(err) {
return t.Connection.GetNotExistError()
} else if t.Fs.IsPermission(err) {
return t.Connection.GetPermissionDeniedError()
}
return err
}
// CheckRead returns an error if read if not allowed
func (t *BaseTransfer) CheckRead() error {
if t.transferQuota.AllowedDLSize == 0 && t.transferQuota.AllowedTotalSize == 0 {

View file

@ -21,6 +21,7 @@ import (
"testing"
"time"
"github.com/pkg/sftp"
"github.com/sftpgo/sdk"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -225,6 +226,10 @@ func TestTransferErrors(t *testing.T) {
conn := NewBaseConnection("id", ProtocolSFTP, "", "", u)
transfer := NewBaseTransfer(file, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload,
0, 0, 0, 0, true, fs, dataprovider.TransferQuota{})
err = transfer.ConvertError(os.ErrNotExist)
assert.ErrorIs(t, err, sftp.ErrSSHFxNoSuchFile)
err = transfer.ConvertError(os.ErrPermission)
assert.ErrorIs(t, err, sftp.ErrSSHFxPermissionDenied)
assert.Nil(t, transfer.cancelFn)
assert.Equal(t, testFile, transfer.GetFsPath())
transfer.SetCancelFn(cancelFn)

View file

@ -67,6 +67,7 @@ func (t *transfer) Read(p []byte) (n int, err error) {
}
if err != nil && err != io.EOF {
t.TransferError(err)
err = t.ConvertError(err)
return
}
t.HandleThrottle()
@ -85,6 +86,7 @@ func (t *transfer) Write(p []byte) (n int, err error) {
}
if err != nil {
t.TransferError(err)
err = t.ConvertError(err)
return
}
t.HandleThrottle()

View file

@ -67,6 +67,7 @@ func (f *httpdFile) Read(p []byte) (n int, err error) {
}
if err != nil && err != io.EOF {
f.TransferError(err)
err = f.ConvertError(err)
return
}
f.HandleThrottle()
@ -91,6 +92,7 @@ func (f *httpdFile) Write(p []byte) (n int, err error) {
}
if err != nil {
f.TransferError(err)
err = f.ConvertError(err)
return
}
f.HandleThrottle()

View file

@ -115,6 +115,7 @@ func (t *transfer) ReadAt(p []byte, off int64) (n int, err error) {
if t.GetType() == common.TransferDownload {
t.TransferError(err)
}
err = t.ConvertError(err)
return
}
t.HandleThrottle()
@ -139,6 +140,7 @@ func (t *transfer) WriteAt(p []byte, off int64) (n int, err error) {
}
if err != nil {
t.TransferError(err)
err = t.ConvertError(err)
return
}
t.HandleThrottle()

View file

@ -145,7 +145,7 @@ func (f *webDavFile) Stat() (os.FileInfo, error) {
}
info, err := f.Fs.Stat(f.GetFsPath())
if err != nil {
return nil, err
return nil, f.Connection.GetFsError(f.Fs, err)
}
if vfs.IsCryptOsFs(f.Fs) {
info = f.Fs.(*vfs.CryptFs).ConvertFileInfo(info)
@ -216,7 +216,7 @@ func (f *webDavFile) Read(p []byte) (n int, err error) {
f.startOffset = 0
f.Unlock()
if e != nil {
return 0, e
return 0, f.Connection.GetFsError(f.Fs, e)
}
}
@ -227,6 +227,7 @@ func (f *webDavFile) Read(p []byte) (n int, err error) {
}
if err != nil && err != io.EOF {
f.TransferError(err)
err = f.ConvertError(err)
return
}
f.HandleThrottle()
@ -249,6 +250,7 @@ func (f *webDavFile) Write(p []byte) (n int, err error) {
}
if err != nil {
f.TransferError(err)
err = f.ConvertError(err)
return
}
f.HandleThrottle()