feat: add error mapping

This commit is contained in:
Samuel N Cui
2023-09-28 22:33:29 +08:00
parent 457f88d526
commit dd07ebc94c
2 changed files with 35 additions and 42 deletions

45
copy.go
View File

@@ -10,7 +10,6 @@ import (
"path"
"sync"
"sync/atomic"
"syscall"
"time"
mapset "github.com/deckarep/golang-set/v2"
@@ -24,9 +23,6 @@ const (
var (
sha256Pool = &sync.Pool{New: func() interface{} { return sha256.New() }}
ErrTargetNoSpace = fmt.Errorf("acp: target have no space")
ErrTargetDropToReadonly = fmt.Errorf("acp: target droped into readonly")
)
func (c *Copyer) copy(ctx context.Context, prepared <-chan *writeJob) <-chan *baseJob {
@@ -126,37 +122,14 @@ func (c *Copyer) write(ctx context.Context, job *writeJob, ch chan<- *baseJob, c
}
if err := os.MkdirAll(path.Dir(target), os.ModePerm); err != nil {
// if no space
if errors.Is(err, syscall.ENOSPC) {
noSpaceDevices.Add(dev)
job.fail(target, fmt.Errorf("%w, mkdir dst dir fail", ErrTargetNoSpace))
continue
}
if errors.Is(err, syscall.EROFS) {
noSpaceDevices.Add(dev)
job.fail(target, fmt.Errorf("%w, mkdir dst dir fail", ErrTargetDropToReadonly))
continue
}
job.fail(target, fmt.Errorf("mkdir dst dir fail, %w", err))
job.fail(target, fmt.Errorf("mkdir dst dir fail, %w", mappingError(err)))
continue
}
file, err := os.OpenFile(target, c.createFlag, job.mode)
if err != nil {
// if no space
if errors.Is(err, syscall.ENOSPC) {
noSpaceDevices.Add(dev)
job.fail(target, fmt.Errorf("%w, open dst file fail", ErrTargetNoSpace))
continue
}
if errors.Is(err, syscall.EROFS) {
noSpaceDevices.Add(dev)
job.fail(target, fmt.Errorf("%w, open dst file fail", ErrTargetDropToReadonly))
continue
}
job.fail(target, fmt.Errorf("open dst file fail, %w", err))
job.fail(target, fmt.Errorf("open dst file fail, %w", mappingError(err)))
continue
}
@@ -182,19 +155,7 @@ func (c *Copyer) write(ctx context.Context, job *writeJob, ch chan<- *baseJob, c
c.reportError(job.path, target, fmt.Errorf("delete failed file has error, %w", err))
}
// if no space
if errors.Is(rerr, syscall.ENOSPC) {
noSpaceDevices.Add(dev)
job.fail(target, fmt.Errorf("%w, write dst file fail", ErrTargetNoSpace))
return
}
if errors.Is(rerr, syscall.EROFS) {
noSpaceDevices.Add(dev)
job.fail(target, fmt.Errorf("%w, write dst file fail", ErrTargetDropToReadonly))
return
}
job.fail(target, fmt.Errorf("write dst file fail, %w", rerr))
job.fail(target, fmt.Errorf("write dst file fail, %w", mappingError(rerr)))
}()
defer file.Close()

View File

@@ -1,8 +1,10 @@
package acp
import (
"errors"
"fmt"
"sync"
"syscall"
"github.com/samuelncui/godf"
)
@@ -11,6 +13,22 @@ const (
defaultDiskUsageFreshInterval = 1024 * 1024 * 1024 * 2
)
var (
ErrTargetNoSpace = fmt.Errorf("acp: target have no space")
ErrTargetDropToReadonly = fmt.Errorf("acp: target droped into readonly")
errorMapping = []errorPair{
{from: syscall.ENOSPC, to: ErrTargetNoSpace},
{from: syscall.EROFS, to: ErrTargetDropToReadonly},
{from: syscall.EIO, to: ErrTargetDropToReadonly},
}
)
type errorPair struct {
from error
to error
}
type diskUsageCache struct {
mountPoint string
freshInterval int64
@@ -49,3 +67,17 @@ func (m *diskUsageCache) check(need int64) error {
return nil
}
func mappingError(err error) error {
if err == nil {
return nil
}
for _, p := range errorMapping {
if errors.Is(err, p.from) {
return fmt.Errorf("%w: %w", p.to, err)
}
}
return err
}