mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
ebcb7d6b40
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>
104 lines
2.7 KiB
Go
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
|
|
}
|