classify grpc errors
This commit is contained in:
49
weed/mount/error_classifier.go
Normal file
49
weed/mount/error_classifier.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package mount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/hanwen/go-fuse/v2/fuse"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func grpcErrorToFuseStatus(err error) fuse.Status {
|
||||||
|
if err == nil {
|
||||||
|
return fuse.OK
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack error for inspection
|
||||||
|
if s, ok := status.FromError(err); ok {
|
||||||
|
switch s.Code() {
|
||||||
|
case codes.OK:
|
||||||
|
return fuse.OK
|
||||||
|
case codes.Canceled, codes.DeadlineExceeded:
|
||||||
|
return fuse.Status(syscall.ETIMEDOUT)
|
||||||
|
case codes.Unavailable:
|
||||||
|
return fuse.Status(syscall.EAGAIN)
|
||||||
|
case codes.ResourceExhausted:
|
||||||
|
return fuse.Status(syscall.EAGAIN) // Or syscall.ENOSPC
|
||||||
|
case codes.PermissionDenied:
|
||||||
|
return fuse.Status(syscall.EACCES)
|
||||||
|
case codes.Unauthenticated:
|
||||||
|
return fuse.Status(syscall.EPERM)
|
||||||
|
case codes.NotFound:
|
||||||
|
return fuse.ENOENT
|
||||||
|
case codes.AlreadyExists:
|
||||||
|
return fuse.Status(syscall.EEXIST)
|
||||||
|
case codes.InvalidArgument:
|
||||||
|
return fuse.EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String matching for errors that don't have proper gRPC codes but are known
|
||||||
|
errStr := err.Error()
|
||||||
|
if strings.Contains(errStr, "transport") {
|
||||||
|
return fuse.Status(syscall.EAGAIN)
|
||||||
|
}
|
||||||
|
// Add other string matches if necessary
|
||||||
|
|
||||||
|
return fuse.EIO
|
||||||
|
}
|
||||||
@@ -40,8 +40,14 @@ func (wfs *WFS) saveEntry(path util.FullPath, entry *filer_pb.Entry) (code fuse.
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("saveEntry %s: %v", path, err)
|
// glog.V(0).Infof("saveEntry %s: %v", path, err)
|
||||||
return fuse.EIO
|
fuseStatus := grpcErrorToFuseStatus(err)
|
||||||
|
if fuseStatus == fuse.EIO {
|
||||||
|
glog.Errorf("saveEntry failed for %s: %v (returning EIO)", path, err)
|
||||||
|
} else {
|
||||||
|
glog.V(1).Infof("saveEntry failed for %s: %v (returning %v)", path, err, fuseStatus)
|
||||||
|
}
|
||||||
|
return fuseStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
return fuse.OK
|
return fuse.OK
|
||||||
|
|||||||
Reference in New Issue
Block a user