| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package validators
- import (
- "database/sql"
- "fmt"
- "yunion.io/x/pkg/util/httputils"
- "yunion.io/x/onecloud/pkg/httperrors"
- "yunion.io/x/onecloud/pkg/util/choices"
- )
- var returnHttpError = true
- type ErrType uintptr
- const (
- ERR_SUCCESS ErrType = iota
- ERR_GENERAL // uncategorized error
- ERR_MISSING_KEY
- ERR_INVALID_TYPE
- ERR_INVALID_CHOICE
- ERR_INVALID_LENGTH
- ERR_NOT_IN_RANGE
- ERR_INVALID_VALUE
- ERR_MODEL_MANAGER
- ERR_MODEL_NOT_FOUND
- )
- var errTypeToString = map[ErrType]string{
- ERR_SUCCESS: "No error",
- ERR_GENERAL: "General error",
- ERR_MISSING_KEY: "Missing key error",
- ERR_INVALID_TYPE: "Invalid type error",
- ERR_INVALID_CHOICE: "Invalid choice error",
- ERR_INVALID_LENGTH: "Invalid length error",
- ERR_NOT_IN_RANGE: "Not in range error",
- ERR_INVALID_VALUE: "Invalid value error",
- ERR_MODEL_MANAGER: "Model manager error",
- ERR_MODEL_NOT_FOUND: "Model not found error",
- }
- func (errType ErrType) String() string {
- s, ok := errTypeToString[errType]
- if ok {
- return s
- }
- return "unknown error"
- }
- type ValidateError struct {
- ErrType ErrType
- Msg string
- }
- func (ve *ValidateError) Error() string {
- return ve.Msg
- }
- func (ve *ValidateError) Cause() error {
- switch ve.ErrType {
- case ERR_GENERAL, ERR_MODEL_MANAGER:
- return httperrors.ErrInternalError // httperrors.NewInternalServerError(errFmt, params...)
- case ERR_MODEL_NOT_FOUND:
- return httperrors.ErrResourceNotFound // httperrors.NewResourceNotFoundError(errFmt, params...)
- default:
- return httperrors.ErrInputParameter // httperrors.NewInputParameterError(errFmt, params...)
- }
- }
- // TODO let each validator provide the error
- func newMissingKeyError(key string) error {
- return newError(ERR_MISSING_KEY, "missing %q", key)
- }
- func newGeneralError(key string, err error) error {
- return newError(ERR_GENERAL, "general error for %q: %s", key, err)
- }
- func newInvalidTypeError(key string, typ string, err error) error {
- return newError(ERR_INVALID_TYPE, "expecting %s type for %q: %s", typ, key, err)
- }
- func newInvalidChoiceError(key string, choices choices.Choices, choice string) error {
- return newError(ERR_INVALID_CHOICE, "invalid %q, want %s, got %s", key, choices, choice)
- }
- func newInvalidIntChoiceError(key string, choices []int64, choice int64) error {
- wantS := ""
- for i, c := range choices {
- if i > 0 {
- wantS += ", "
- }
- wantS += fmt.Sprintf("%d", c)
- }
- gotS := fmt.Sprintf("%d", choice)
- return newError(ERR_INVALID_CHOICE, "invalid %q, want %s, got %s", key, wantS, gotS)
- }
- func newStringTooShortError(key string, got, want int) error {
- return newError(ERR_INVALID_LENGTH, "%q too short, got %d, min %d", key, got, want)
- }
- func newStringTooLongError(key string, got, want int) error {
- return newError(ERR_INVALID_LENGTH, "%q too long, got %d, max %d", key, got, want)
- }
- func newNotInRangeError(key string, value, lower, upper int64) error {
- return newError(ERR_NOT_IN_RANGE, "invalid %q: %d, want [%d,%d]", key, value, lower, upper)
- }
- func newInvalidValueError(key string, value string) error {
- return newError(ERR_INVALID_VALUE, "invalid %q: %s", key, value)
- }
- func newInvalidValueErrorEx(key string, err error) error {
- return newError(ERR_INVALID_VALUE, "invalid %q: %v", key, err)
- }
- func newInvalidStructError(key string, err error) error {
- errFmt := "invalid %q: "
- params := []interface{}{key}
- jsonClientErr, ok := err.(*httputils.JSONClientError)
- if ok {
- errFmt += httputils.MsgTmplToFmt(jsonClientErr.Data.Id)
- params = append(params, jsonClientErr.Data.Fields...)
- }
- return newError(ERR_INVALID_VALUE, errFmt, params...)
- }
- func newModelManagerError(modelKeyword string) error {
- return newError(ERR_MODEL_MANAGER, "failed getting model manager for %q", modelKeyword)
- }
- func newModelNotFoundError(modelKeyword, idOrName string, err error) error {
- errFmt := "cannot find %q with id/name %q"
- params := []interface{}{modelKeyword, idOrName}
- if err != nil && err != sql.ErrNoRows {
- errFmt += ": %s"
- params = append(params, err.Error())
- }
- return newError(ERR_MODEL_NOT_FOUND, errFmt, params...)
- }
- func newError(typ ErrType, errFmt string, params ...interface{}) error {
- if typ == ERR_SUCCESS {
- return nil
- }
- errFmt = fmt.Sprintf("%s: %s", typ, errFmt)
- if returnHttpError {
- switch typ {
- case ERR_GENERAL, ERR_MODEL_MANAGER:
- return httperrors.NewInternalServerError(errFmt, params...)
- case ERR_MODEL_NOT_FOUND:
- return httperrors.NewResourceNotFoundError(errFmt, params...)
- default:
- return httperrors.NewInputParameterError(errFmt, params...)
- }
- }
- err := &ValidateError{
- ErrType: typ,
- Msg: fmt.Sprintf(errFmt, params...),
- }
- return err
- }
- func IsModelNotFoundError(err error) bool {
- ve, ok := err.(*ValidateError)
- if ok && ve.ErrType == ERR_MODEL_NOT_FOUND {
- return true
- }
- return false
- }
|