1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/volume/store/errors.go
Brian Goff ebcb7d6b40 Remove string checking in API error handling
Use strongly typed errors to set HTTP status codes.
Error interfaces are defined in the api/errors package and errors
returned from controllers are checked against these interfaces.

Errors can be wraeped in a pkg/errors.Causer, as long as somewhere in the
line of causes one of the interfaces is implemented. The special error
interfaces take precedence over Causer, meaning if both Causer and one
of the new error interfaces are implemented, the Causer is not
traversed.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2017-08-15 16:01:11 -04:00

104 lines
2.7 KiB
Go

package store
import (
"strings"
)
const (
// errVolumeInUse is a typed error returned when trying to remove a volume that is currently in use by a container
errVolumeInUse conflictError = "volume is in use"
// errNoSuchVolume is a typed error returned if the requested volume doesn't exist in the volume store
errNoSuchVolume notFoundError = "no such volume"
// errInvalidName is a typed error returned when creating a volume with a name that is not valid on the platform
errInvalidName invalidName = "volume name is not valid on this platform"
// errNameConflict is a typed error returned on create when a volume exists with the given name, but for a different driver
errNameConflict conflictError = "volume name must be unique"
)
type conflictError string
func (e conflictError) Error() string {
return string(e)
}
func (conflictError) Conflict() {}
type notFoundError string
func (e notFoundError) Error() string {
return string(e)
}
func (notFoundError) NotFound() {}
type invalidName string
func (e invalidName) Error() string {
return string(e)
}
func (invalidName) InvalidParameter() {}
// OpErr is the error type returned by functions in the store package. It describes
// the operation, volume name, and error.
type OpErr struct {
// Err is the error that occurred during the operation.
Err error
// Op is the operation which caused the error, such as "create", or "list".
Op string
// Name is the name of the resource being requested for this op, typically the volume name or the driver name.
Name string
// Refs is the list of references associated with the resource.
Refs []string
}
// Error satisfies the built-in error interface type.
func (e *OpErr) Error() string {
if e == nil {
return "<nil>"
}
s := e.Op
if e.Name != "" {
s = s + " " + e.Name
}
s = s + ": " + e.Err.Error()
if len(e.Refs) > 0 {
s = s + " - " + "[" + strings.Join(e.Refs, ", ") + "]"
}
return s
}
// Cause returns the error the caused this error
func (e *OpErr) Cause() error {
return e.Err
}
// IsInUse returns a boolean indicating whether the error indicates that a
// volume is in use
func IsInUse(err error) bool {
return isErr(err, errVolumeInUse)
}
// IsNotExist returns a boolean indicating whether the error indicates that the volume does not exist
func IsNotExist(err error) bool {
return isErr(err, errNoSuchVolume)
}
// IsNameConflict returns a boolean indicating whether the error indicates that a
// volume name is already taken
func IsNameConflict(err error) bool {
return isErr(err, errNameConflict)
}
type causal interface {
Cause() error
}
func isErr(err error, expected error) bool {
switch pe := err.(type) {
case nil:
return false
case causal:
return isErr(pe.Cause(), expected)
}
return err == expected
}