errors.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package validators
  15. import (
  16. "database/sql"
  17. "fmt"
  18. "yunion.io/x/pkg/util/httputils"
  19. "yunion.io/x/onecloud/pkg/httperrors"
  20. "yunion.io/x/onecloud/pkg/util/choices"
  21. )
  22. var returnHttpError = true
  23. type ErrType uintptr
  24. const (
  25. ERR_SUCCESS ErrType = iota
  26. ERR_GENERAL // uncategorized error
  27. ERR_MISSING_KEY
  28. ERR_INVALID_TYPE
  29. ERR_INVALID_CHOICE
  30. ERR_INVALID_LENGTH
  31. ERR_NOT_IN_RANGE
  32. ERR_INVALID_VALUE
  33. ERR_MODEL_MANAGER
  34. ERR_MODEL_NOT_FOUND
  35. )
  36. var errTypeToString = map[ErrType]string{
  37. ERR_SUCCESS: "No error",
  38. ERR_GENERAL: "General error",
  39. ERR_MISSING_KEY: "Missing key error",
  40. ERR_INVALID_TYPE: "Invalid type error",
  41. ERR_INVALID_CHOICE: "Invalid choice error",
  42. ERR_INVALID_LENGTH: "Invalid length error",
  43. ERR_NOT_IN_RANGE: "Not in range error",
  44. ERR_INVALID_VALUE: "Invalid value error",
  45. ERR_MODEL_MANAGER: "Model manager error",
  46. ERR_MODEL_NOT_FOUND: "Model not found error",
  47. }
  48. func (errType ErrType) String() string {
  49. s, ok := errTypeToString[errType]
  50. if ok {
  51. return s
  52. }
  53. return "unknown error"
  54. }
  55. type ValidateError struct {
  56. ErrType ErrType
  57. Msg string
  58. }
  59. func (ve *ValidateError) Error() string {
  60. return ve.Msg
  61. }
  62. func (ve *ValidateError) Cause() error {
  63. switch ve.ErrType {
  64. case ERR_GENERAL, ERR_MODEL_MANAGER:
  65. return httperrors.ErrInternalError // httperrors.NewInternalServerError(errFmt, params...)
  66. case ERR_MODEL_NOT_FOUND:
  67. return httperrors.ErrResourceNotFound // httperrors.NewResourceNotFoundError(errFmt, params...)
  68. default:
  69. return httperrors.ErrInputParameter // httperrors.NewInputParameterError(errFmt, params...)
  70. }
  71. }
  72. // TODO let each validator provide the error
  73. func newMissingKeyError(key string) error {
  74. return newError(ERR_MISSING_KEY, "missing %q", key)
  75. }
  76. func newGeneralError(key string, err error) error {
  77. return newError(ERR_GENERAL, "general error for %q: %s", key, err)
  78. }
  79. func newInvalidTypeError(key string, typ string, err error) error {
  80. return newError(ERR_INVALID_TYPE, "expecting %s type for %q: %s", typ, key, err)
  81. }
  82. func newInvalidChoiceError(key string, choices choices.Choices, choice string) error {
  83. return newError(ERR_INVALID_CHOICE, "invalid %q, want %s, got %s", key, choices, choice)
  84. }
  85. func newInvalidIntChoiceError(key string, choices []int64, choice int64) error {
  86. wantS := ""
  87. for i, c := range choices {
  88. if i > 0 {
  89. wantS += ", "
  90. }
  91. wantS += fmt.Sprintf("%d", c)
  92. }
  93. gotS := fmt.Sprintf("%d", choice)
  94. return newError(ERR_INVALID_CHOICE, "invalid %q, want %s, got %s", key, wantS, gotS)
  95. }
  96. func newStringTooShortError(key string, got, want int) error {
  97. return newError(ERR_INVALID_LENGTH, "%q too short, got %d, min %d", key, got, want)
  98. }
  99. func newStringTooLongError(key string, got, want int) error {
  100. return newError(ERR_INVALID_LENGTH, "%q too long, got %d, max %d", key, got, want)
  101. }
  102. func newNotInRangeError(key string, value, lower, upper int64) error {
  103. return newError(ERR_NOT_IN_RANGE, "invalid %q: %d, want [%d,%d]", key, value, lower, upper)
  104. }
  105. func newInvalidValueError(key string, value string) error {
  106. return newError(ERR_INVALID_VALUE, "invalid %q: %s", key, value)
  107. }
  108. func newInvalidValueErrorEx(key string, err error) error {
  109. return newError(ERR_INVALID_VALUE, "invalid %q: %v", key, err)
  110. }
  111. func newInvalidStructError(key string, err error) error {
  112. errFmt := "invalid %q: "
  113. params := []interface{}{key}
  114. jsonClientErr, ok := err.(*httputils.JSONClientError)
  115. if ok {
  116. errFmt += httputils.MsgTmplToFmt(jsonClientErr.Data.Id)
  117. params = append(params, jsonClientErr.Data.Fields...)
  118. }
  119. return newError(ERR_INVALID_VALUE, errFmt, params...)
  120. }
  121. func newModelManagerError(modelKeyword string) error {
  122. return newError(ERR_MODEL_MANAGER, "failed getting model manager for %q", modelKeyword)
  123. }
  124. func newModelNotFoundError(modelKeyword, idOrName string, err error) error {
  125. errFmt := "cannot find %q with id/name %q"
  126. params := []interface{}{modelKeyword, idOrName}
  127. if err != nil && err != sql.ErrNoRows {
  128. errFmt += ": %s"
  129. params = append(params, err.Error())
  130. }
  131. return newError(ERR_MODEL_NOT_FOUND, errFmt, params...)
  132. }
  133. func newError(typ ErrType, errFmt string, params ...interface{}) error {
  134. if typ == ERR_SUCCESS {
  135. return nil
  136. }
  137. errFmt = fmt.Sprintf("%s: %s", typ, errFmt)
  138. if returnHttpError {
  139. switch typ {
  140. case ERR_GENERAL, ERR_MODEL_MANAGER:
  141. return httperrors.NewInternalServerError(errFmt, params...)
  142. case ERR_MODEL_NOT_FOUND:
  143. return httperrors.NewResourceNotFoundError(errFmt, params...)
  144. default:
  145. return httperrors.NewInputParameterError(errFmt, params...)
  146. }
  147. }
  148. err := &ValidateError{
  149. ErrType: typ,
  150. Msg: fmt.Sprintf(errFmt, params...),
  151. }
  152. return err
  153. }
  154. func IsModelNotFoundError(err error) bool {
  155. ve, ok := err.(*ValidateError)
  156. if ok && ve.ErrType == ERR_MODEL_NOT_FOUND {
  157. return true
  158. }
  159. return false
  160. }