131 lines
2.7 KiB
Go
131 lines
2.7 KiB
Go
package storage
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
type ErrorKind string
|
|
|
|
const (
|
|
ErrNotFound ErrorKind = "not_found"
|
|
ErrAlreadyExist ErrorKind = "already_exists"
|
|
ErrNotEmpty ErrorKind = "not_empty"
|
|
ErrInvalidPath ErrorKind = "invalid_path"
|
|
ErrConflict ErrorKind = "conflict"
|
|
ErrPermission ErrorKind = "permission"
|
|
ErrTemporary ErrorKind = "temporary"
|
|
ErrUnsupported ErrorKind = "unsupported"
|
|
ErrUnknown ErrorKind = "unknown"
|
|
)
|
|
|
|
const (
|
|
OpValidatePath = "validate path"
|
|
OpReadFile = "read file"
|
|
OpOpenReader = "open reader"
|
|
OpWriteFile = "write file"
|
|
OpWriteFrom = "write stream"
|
|
OpStat = "stat"
|
|
OpWalk = "walk"
|
|
OpHasAny = "has any"
|
|
OpDeleteManagedOutputs = "delete managed outputs"
|
|
OpDeleteManagedBundle = "delete managed bundle"
|
|
OpDeletePrefix = "delete prefix"
|
|
OpRegisterBackend = "register backend"
|
|
OpOpenBackend = "open backend"
|
|
)
|
|
|
|
type Error struct {
|
|
Op string
|
|
Backend string
|
|
Path string
|
|
Kind ErrorKind
|
|
Err error
|
|
}
|
|
|
|
func NewError(op, backend, path string, kind ErrorKind, err error) *Error {
|
|
return &Error{
|
|
Op: op,
|
|
Backend: backend,
|
|
Path: path,
|
|
Kind: kind,
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
func (e *Error) Error() string {
|
|
if e == nil {
|
|
return "<nil>"
|
|
}
|
|
message := e.Op
|
|
if e.Backend != "" {
|
|
message += " " + e.Backend
|
|
}
|
|
if e.Path != "" {
|
|
message += " " + e.Path
|
|
}
|
|
if e.Kind != "" {
|
|
message += ": " + string(e.Kind)
|
|
}
|
|
if e.Err != nil {
|
|
message += ": " + e.Err.Error()
|
|
}
|
|
return message
|
|
}
|
|
|
|
func (e *Error) Unwrap() error {
|
|
if e == nil {
|
|
return nil
|
|
}
|
|
return e.Err
|
|
}
|
|
|
|
func (e *Error) Is(target error) bool {
|
|
var targetError *Error
|
|
if !errors.As(target, &targetError) {
|
|
return false
|
|
}
|
|
return targetError.Kind == "" || e.Kind == targetError.Kind
|
|
}
|
|
|
|
func Errorf(op, backend, path string, kind ErrorKind, format string, args ...any) *Error {
|
|
return NewError(op, backend, path, kind, fmt.Errorf(format, args...))
|
|
}
|
|
|
|
func IsKind(err error, kind ErrorKind) bool {
|
|
var storageErr *Error
|
|
return errors.As(err, &storageErr) && storageErr.Kind == kind
|
|
}
|
|
|
|
func IsNotFound(err error) bool {
|
|
return IsKind(err, ErrNotFound)
|
|
}
|
|
|
|
func IsAlreadyExists(err error) bool {
|
|
return IsKind(err, ErrAlreadyExist)
|
|
}
|
|
|
|
func IsNotEmpty(err error) bool {
|
|
return IsKind(err, ErrNotEmpty)
|
|
}
|
|
|
|
func IsInvalidPath(err error) bool {
|
|
return IsKind(err, ErrInvalidPath)
|
|
}
|
|
|
|
func IsConflict(err error) bool {
|
|
return IsKind(err, ErrConflict)
|
|
}
|
|
|
|
func IsPermission(err error) bool {
|
|
return IsKind(err, ErrPermission)
|
|
}
|
|
|
|
func IsTemporary(err error) bool {
|
|
return IsKind(err, ErrTemporary)
|
|
}
|
|
|
|
func IsUnsupported(err error) bool {
|
|
return IsKind(err, ErrUnsupported)
|
|
}
|