errors.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package store
  2. import (
  3. "strings"
  4. )
  5. const (
  6. // errVolumeInUse is a typed error returned when trying to remove a volume that is currently in use by a container
  7. errVolumeInUse conflictError = "volume is in use"
  8. // errNoSuchVolume is a typed error returned if the requested volume doesn't exist in the volume store
  9. errNoSuchVolume notFoundError = "no such volume"
  10. // errNameConflict is a typed error returned on create when a volume exists with the given name, but for a different driver
  11. errNameConflict conflictError = "volume name must be unique"
  12. )
  13. type conflictError string
  14. func (e conflictError) Error() string {
  15. return string(e)
  16. }
  17. func (conflictError) Conflict() {}
  18. type notFoundError string
  19. func (e notFoundError) Error() string {
  20. return string(e)
  21. }
  22. func (notFoundError) NotFound() {}
  23. // OpErr is the error type returned by functions in the store package. It describes
  24. // the operation, volume name, and error.
  25. type OpErr struct {
  26. // Err is the error that occurred during the operation.
  27. Err error
  28. // Op is the operation which caused the error, such as "create", or "list".
  29. Op string
  30. // Name is the name of the resource being requested for this op, typically the volume name or the driver name.
  31. Name string
  32. // Refs is the list of references associated with the resource.
  33. Refs []string
  34. }
  35. // Error satisfies the built-in error interface type.
  36. func (e *OpErr) Error() string {
  37. if e == nil {
  38. return "<nil>"
  39. }
  40. s := e.Op
  41. if e.Name != "" {
  42. s = s + " " + e.Name
  43. }
  44. s = s + ": " + e.Err.Error()
  45. if len(e.Refs) > 0 {
  46. s = s + " - " + "[" + strings.Join(e.Refs, ", ") + "]"
  47. }
  48. return s
  49. }
  50. // Cause returns the error the caused this error
  51. func (e *OpErr) Cause() error {
  52. return e.Err
  53. }
  54. // IsInUse returns a boolean indicating whether the error indicates that a
  55. // volume is in use
  56. func IsInUse(err error) bool {
  57. return isErr(err, errVolumeInUse)
  58. }
  59. // IsNotExist returns a boolean indicating whether the error indicates that the volume does not exist
  60. func IsNotExist(err error) bool {
  61. return isErr(err, errNoSuchVolume)
  62. }
  63. // IsNameConflict returns a boolean indicating whether the error indicates that a
  64. // volume name is already taken
  65. func IsNameConflict(err error) bool {
  66. return isErr(err, errNameConflict)
  67. }
  68. type causal interface {
  69. Cause() error
  70. }
  71. func isErr(err error, expected error) bool {
  72. switch pe := err.(type) {
  73. case nil:
  74. return false
  75. case causal:
  76. return isErr(pe.Cause(), expected)
  77. }
  78. return err == expected
  79. }