mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-29 03:51:54 +08:00
fix: recode error handling to make conform with error handling standard
This commit is contained in:
@@ -112,7 +112,7 @@ func newInvalidStructError(key string, err error) error {
|
||||
params := []interface{}{key}
|
||||
jsonClientErr, ok := err.(*httputils.JSONClientError)
|
||||
if ok {
|
||||
errFmt += httperrors.MsgTmplToFmt(jsonClientErr.Data.Id)
|
||||
errFmt += httputils.MsgTmplToFmt(jsonClientErr.Data.Id)
|
||||
for _, f := range jsonClientErr.Data.Fields {
|
||||
params = append(params, f)
|
||||
}
|
||||
|
||||
+11
-11
@@ -16,6 +16,8 @@ package cloudprovider
|
||||
|
||||
import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -27,15 +29,13 @@ const (
|
||||
CloudVMStatusDeploying = "deploying"
|
||||
CloudVMStatusOther = "other"
|
||||
|
||||
ErrUnauthenticated = errors.Error("not authenticated")
|
||||
ErrUnauthorized = errors.Error("not authorized")
|
||||
ErrNotFound = errors.Error("id not found")
|
||||
ErrDuplicateId = errors.Error("duplicate id")
|
||||
ErrInvalidStatus = errors.Error("invalid status")
|
||||
ErrTimeout = errors.Error("timeout")
|
||||
ErrNotImplemented = errors.Error("Not implemented")
|
||||
ErrNotSupported = errors.Error("Not supported")
|
||||
ErrInvalidProvider = errors.Error("Invalid provider")
|
||||
ErrNoBalancePermission = errors.Error("No balance permission")
|
||||
ErrBadRequest = errors.Error("bad request")
|
||||
ErrNotFound = errors.ErrNotFound
|
||||
ErrDuplicateId = errors.ErrDuplicateId
|
||||
ErrInvalidStatus = errors.ErrInvalidStatus
|
||||
ErrTimeout = errors.ErrTimeout
|
||||
ErrNotImplemented = errors.ErrNotImplemented
|
||||
ErrNotSupported = errors.ErrNotSupported
|
||||
|
||||
ErrInvalidProvider = httperrors.ErrInvalidProvider
|
||||
ErrNoBalancePermission = httperrors.ErrNoBalancePermission
|
||||
)
|
||||
|
||||
+130
-12
@@ -19,16 +19,134 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
ErrUnauthenticated = errors.Error("not authenticated")
|
||||
ErrUnauthorized = errors.Error("not authorized")
|
||||
ErrNotFound = errors.Error("id not found")
|
||||
ErrDuplicateId = errors.Error("duplicate id")
|
||||
ErrInvalidStatus = errors.Error("invalid status")
|
||||
ErrTimeout = errors.Error("timeout")
|
||||
ErrNotImplemented = errors.Error("Not implemented")
|
||||
ErrNotSupported = errors.Error("Not supported")
|
||||
ErrBadRequest = errors.Error("bad request")
|
||||
ErrOutOfRange = errors.Error("out of range")
|
||||
ErrForbidden = errors.Error("not allowed")
|
||||
ErrOutOfLimit = errors.Error("out of limit")
|
||||
ErrBadGateway = errors.Error("BadGateway")
|
||||
ErrNotImplemented = errors.ErrNotImplemented
|
||||
ErrInternalError = errors.Error("InternalServerError")
|
||||
ErrResourceNotReady = errors.Error("ResourceNotReadyError")
|
||||
ErrPayment = errors.Error("PaymentError")
|
||||
|
||||
ErrImageNotFound = errors.Error("ImageNotFoundError")
|
||||
ErrResourceNotFound = errors.Error("ResourceNotFoundError")
|
||||
ErrSpecNotFound = errors.Error("SpecNotFoundError")
|
||||
ErrActionNotFound = errors.Error("ActionNotFoundError")
|
||||
ErrTenantNotFound = errors.Error("TenantNotFoundError")
|
||||
ErrUserNotFound = errors.Error("UserNotFoundError")
|
||||
|
||||
ErrServerStatus = errors.Error("ServerStatusError")
|
||||
ErrInvalidStatus = errors.ErrInvalidStatus
|
||||
|
||||
ErrInputParameter = errors.Error("InputParameterError")
|
||||
ErrWeakPassword = errors.Error("WeakPasswordError")
|
||||
ErrMissingParameter = errors.Error("MissingParameterError")
|
||||
|
||||
ErrInsufficientResource = errors.Error("InsufficientResourceError")
|
||||
ErrOutOfResource = errors.Error("OutOfResource")
|
||||
ErrOutOfQuota = errors.Error("OutOfQuotaError")
|
||||
ErrOutOfRange = errors.Error("OutOfRange")
|
||||
ErrOutOfLimit = errors.Error("OutOfLimit")
|
||||
|
||||
ErrNotSufficientPrivilege = errors.Error("NotSufficientPrivilegeError")
|
||||
|
||||
ErrUnsupportedOperation = errors.Error("UnsupportOperationError")
|
||||
ErrNotSupported = errors.ErrNotSupported
|
||||
|
||||
ErrNotEmpty = errors.Error("NotEmptyError")
|
||||
ErrBadRequest = errors.Error("BadRequestError")
|
||||
|
||||
ErrUnauthorized = errors.Error("UnauthorizedError")
|
||||
ErrInvalidCredential = errors.Error("InvalidCredentialError")
|
||||
ErrUnauthenticated = ErrInvalidCredential
|
||||
ErrForbidden = errors.Error("ForbiddenError")
|
||||
|
||||
ErrNotFound = errors.ErrNotFound
|
||||
|
||||
ErrNotAcceptable = errors.Error("NotAcceptableError")
|
||||
|
||||
ErrDuplicateName = errors.Error("DuplicateNameError")
|
||||
ErrDuplicateResource = errors.Error("DuplicateResourceError")
|
||||
ErrConflict = errors.Error("ConflictError")
|
||||
ErrDuplicateId = errors.ErrDuplicateId
|
||||
|
||||
ErrResourceBusy = errors.Error("ResourceBusyError")
|
||||
ErrRequireLicense = errors.Error("RequireLicenseError")
|
||||
|
||||
ErrTimeout = errors.ErrTimeout
|
||||
ErrProtectedResource = errors.Error("ProtectedResourceError")
|
||||
ErrNoProject = errors.Error("NoProjectError")
|
||||
|
||||
ErrInvalidProvider = errors.Error("InvalidProvider")
|
||||
ErrNoBalancePermission = errors.Error("NoBalancePermission")
|
||||
)
|
||||
|
||||
var (
|
||||
httpErrorCode = map[errors.Error]int{
|
||||
errors.ErrClient: 400,
|
||||
errors.ErrServer: 500,
|
||||
errors.ErrUnclassified: 500,
|
||||
|
||||
ErrInvalidProvider: 400,
|
||||
ErrNoBalancePermission: 403,
|
||||
|
||||
ErrBadGateway: 502,
|
||||
ErrNotImplemented: 501,
|
||||
ErrInternalError: 500,
|
||||
ErrResourceNotReady: 500,
|
||||
ErrPayment: 402,
|
||||
|
||||
ErrImageNotFound: 404,
|
||||
ErrResourceNotFound: 404,
|
||||
ErrSpecNotFound: 404,
|
||||
ErrActionNotFound: 404,
|
||||
ErrTenantNotFound: 404,
|
||||
ErrUserNotFound: 404,
|
||||
|
||||
ErrServerStatus: 400,
|
||||
ErrInvalidStatus: 400,
|
||||
|
||||
ErrInputParameter: 400,
|
||||
ErrWeakPassword: 400,
|
||||
ErrMissingParameter: 400,
|
||||
|
||||
ErrInsufficientResource: 400,
|
||||
ErrOutOfResource: 500,
|
||||
ErrOutOfQuota: 400,
|
||||
ErrOutOfRange: 400,
|
||||
ErrOutOfLimit: 400,
|
||||
|
||||
ErrNotSufficientPrivilege: 403,
|
||||
|
||||
ErrUnsupportedOperation: 406,
|
||||
ErrNotSupported: 406,
|
||||
|
||||
ErrNotEmpty: 406,
|
||||
ErrBadRequest: 400,
|
||||
|
||||
ErrUnauthorized: 401,
|
||||
ErrInvalidCredential: 401,
|
||||
ErrForbidden: 403,
|
||||
|
||||
ErrNotFound: 404,
|
||||
|
||||
ErrNotAcceptable: 406,
|
||||
|
||||
ErrDuplicateName: 409,
|
||||
ErrDuplicateResource: 409,
|
||||
ErrConflict: 409,
|
||||
ErrDuplicateId: 409,
|
||||
|
||||
ErrResourceBusy: 409,
|
||||
|
||||
ErrRequireLicense: 402,
|
||||
|
||||
ErrTimeout: 504,
|
||||
ErrProtectedResource: 403,
|
||||
ErrNoProject: 403,
|
||||
}
|
||||
)
|
||||
|
||||
func RegisterErrorHttpCode(err errors.Error, code int) {
|
||||
if _, ok := httpErrorCode[err]; ok {
|
||||
panic("Error has been registered: " + string(err))
|
||||
}
|
||||
httpErrorCode[err] = code
|
||||
}
|
||||
|
||||
+69
-184
@@ -15,156 +15,45 @@
|
||||
package httperrors
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
)
|
||||
|
||||
func NewJsonClientError(code int, title string, msg string, error httputils.Error) *httputils.JSONClientError {
|
||||
err := httputils.JSONClientError{Code: code, Class: title, Details: msg, Data: error}
|
||||
return &err
|
||||
}
|
||||
|
||||
func msgFmtToTmpl(msgFmt string) string {
|
||||
// 将%s %d之类格式化字符串转换成{0}、{1}格式
|
||||
// 注意: 1.不支持复杂类型的转换例如%.2f , %[1]d, % x
|
||||
// 2.原始msgFmt中如果包含{0},{1}形式的字符串同样会引发错误。
|
||||
// 在抛出error msgFmt时应注意避免
|
||||
fmtstr := false
|
||||
lst := []rune(msgFmt)
|
||||
lastIndex := len(lst) - 1
|
||||
temp := bytes.Buffer{}
|
||||
index := 0
|
||||
for i, c := range lst {
|
||||
switch c {
|
||||
case '%':
|
||||
if fmtstr || i == lastIndex {
|
||||
temp.WriteRune(c)
|
||||
fmtstr = false
|
||||
} else {
|
||||
fmtstr = true
|
||||
}
|
||||
case 'v', 'T', 't', 'b', 'c', 'd', 'o', 'q', 'x', 'X', 'U', 'e', 'E', 'f', 'F', 'g', 'G', 's', 'p':
|
||||
if fmtstr {
|
||||
temp.WriteRune('{')
|
||||
temp.WriteString(fmt.Sprintf("%d", index))
|
||||
temp.WriteRune('}')
|
||||
index++
|
||||
fmtstr = false
|
||||
} else {
|
||||
temp.WriteRune(c)
|
||||
}
|
||||
|
||||
default:
|
||||
if fmtstr {
|
||||
temp.WriteRune('%')
|
||||
}
|
||||
temp.WriteRune(c)
|
||||
fmtstr = false
|
||||
}
|
||||
}
|
||||
|
||||
return temp.String()
|
||||
}
|
||||
|
||||
func MsgTmplToFmt(tmpl string) string {
|
||||
return msgTmplToFmt(tmpl)
|
||||
}
|
||||
|
||||
func msgTmplToFmt(tmpl string) string {
|
||||
b := &bytes.Buffer{}
|
||||
for i := 0; i < len(tmpl); {
|
||||
r := tmpl[i]
|
||||
if r != '{' {
|
||||
b.WriteByte(r)
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
j := i + 1
|
||||
for ; j < len(tmpl); j++ {
|
||||
r := tmpl[j]
|
||||
if r < '0' || r > '9' {
|
||||
break
|
||||
}
|
||||
}
|
||||
if j == len(tmpl) {
|
||||
b.WriteString(tmpl[i:])
|
||||
return b.String()
|
||||
}
|
||||
if j > i+1 && tmpl[j] == '}' {
|
||||
b.WriteString("%s")
|
||||
i = j + 1
|
||||
} else {
|
||||
b.WriteString(tmpl[i:j])
|
||||
i = j
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func errorMessage(msgFmt string, params ...interface{}) (string, httputils.Error) {
|
||||
fields := make([]string, len(params))
|
||||
for i, v := range params {
|
||||
fields[i] = fmt.Sprint(v)
|
||||
}
|
||||
|
||||
err := httputils.Error{
|
||||
Id: msgFmtToTmpl(msgFmt),
|
||||
Fields: fields,
|
||||
}
|
||||
|
||||
msg := msgFmt
|
||||
if len(params) > 0 {
|
||||
msg = fmt.Sprintf(msg, params...)
|
||||
}
|
||||
return msg, err
|
||||
}
|
||||
|
||||
func NewBadGatewayError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(502, "BadGateway", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrBadGateway], string(ErrBadGateway), msg, params...)
|
||||
}
|
||||
|
||||
func NewNotImplementedError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(501, "NotImplemented", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrNotImplemented], string(ErrNotImplemented), msg, params...)
|
||||
}
|
||||
|
||||
func NewInternalServerError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(500, "InternalServerError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrInternalError], string(ErrInternalError), msg, params...)
|
||||
}
|
||||
|
||||
func NewResourceNotReadyError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(500, "ResourceNotReadyError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrResourceNotReady], string(ErrResourceNotReady), msg, params...)
|
||||
}
|
||||
|
||||
func NewOutOfResourceError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(500, "NewOutOfResourceError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrOutOfResource], string(ErrOutOfResource), msg, params...)
|
||||
}
|
||||
|
||||
func NewServerStatusError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(400, "ServerStatusError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrServerStatus], string(ErrServerStatus), msg, params...)
|
||||
}
|
||||
|
||||
func NewPaymentError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(402, "PaymentError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrPayment], string(ErrPayment), msg, params...)
|
||||
}
|
||||
|
||||
func NewImageNotFoundError(imageId string) *httputils.JSONClientError {
|
||||
msg, err := errorMessage("Image %s not found", imageId)
|
||||
return NewJsonClientError(404, "ImageNotFoundError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrImageNotFound], string(ErrImageNotFound), "Image %s not found", imageId)
|
||||
}
|
||||
|
||||
func NewResourceNotFoundError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(404, "ResourceNotFoundError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrResourceNotFound], string(ErrResourceNotFound), msg, params...)
|
||||
}
|
||||
|
||||
func NewResourceNotFoundError2(keyword, id string) *httputils.JSONClientError {
|
||||
@@ -172,145 +61,141 @@ func NewResourceNotFoundError2(keyword, id string) *httputils.JSONClientError {
|
||||
}
|
||||
|
||||
func NewSpecNotFoundError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(404, "SpecNotFoundError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrSpecNotFound], string(ErrSpecNotFound), msg, params...)
|
||||
}
|
||||
|
||||
func NewActionNotFoundError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(404, "ActionNotFoundError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrActionNotFound], string(ErrActionNotFound), msg, params...)
|
||||
}
|
||||
|
||||
func NewTenantNotFoundError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(404, "TenantNotFoundError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrTenantNotFound], string(ErrTenantNotFound), msg, params...)
|
||||
}
|
||||
|
||||
func NewUserNotFoundError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(404, "UserNotFoundError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrUserNotFound], string(ErrUserNotFound), msg, params...)
|
||||
}
|
||||
|
||||
func NewInvalidStatusError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(400, "InvalidStatusError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrInvalidStatus], string(ErrInvalidStatus), msg, params...)
|
||||
}
|
||||
|
||||
func NewInputParameterError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(400, "InputParameterError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrInputParameter], string(ErrInputParameter), msg, params...)
|
||||
}
|
||||
|
||||
func NewWeakPasswordError() *httputils.JSONClientError {
|
||||
msg, err := errorMessage("password must be 12 chars of at least one digit, letter, uppercase letter and punctuate")
|
||||
return NewJsonClientError(400, "WeakPasswordError", msg, err)
|
||||
msg := ("password must be 12 chars of at least one digit, letter, uppercase letter and punctuate")
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrWeakPassword], string(ErrWeakPassword), msg)
|
||||
}
|
||||
|
||||
func NewMissingParameterError(paramName string) *httputils.JSONClientError {
|
||||
msg, err := errorMessage("Missing parameter %s", paramName)
|
||||
return NewJsonClientError(400, "MissingParameterError", msg, err)
|
||||
msg := "Missing parameter %s"
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrMissingParameter], string(ErrMissingParameter), msg, paramName)
|
||||
}
|
||||
|
||||
func NewInsufficientResourceError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(400, "InsufficientResourceError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrInsufficientResource], string(ErrInsufficientResource), msg, params...)
|
||||
}
|
||||
|
||||
func NewOutOfQuotaError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(400, "OutOfQuotaError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrOutOfQuota], string(ErrOutOfQuota), msg, params...)
|
||||
}
|
||||
|
||||
func NewOutOfRangeError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrOutOfRange], string(ErrOutOfRange), msg, params...)
|
||||
}
|
||||
|
||||
func NewOutOfLimitError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrOutOfLimit], string(ErrOutOfLimit), msg, params...)
|
||||
}
|
||||
|
||||
func NewNotSufficientPrivilegeError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(403, "NotSufficientPrivilegeError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrNotSufficientPrivilege], string(ErrNotSufficientPrivilege), msg, params...)
|
||||
}
|
||||
|
||||
func NewUnsupportOperationError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(406, "UnsupportOperationError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrUnsupportedOperation], string(ErrUnsupportedOperation), msg, params...)
|
||||
}
|
||||
|
||||
func NewNotSupportedError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrNotSupported], string(ErrNotSupported), msg, params...)
|
||||
}
|
||||
|
||||
func NewNotEmptyError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(406, "NotEmptyError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrNotEmpty], string(ErrNotEmpty), msg, params...)
|
||||
}
|
||||
|
||||
func NewBadRequestError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(400, "BadRequestError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrBadRequest], string(ErrBadRequest), msg, params...)
|
||||
}
|
||||
|
||||
func NewUnauthorizedError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(401, "UnauthorizedError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrUnauthorized], string(ErrUnauthorized), msg, params...)
|
||||
}
|
||||
|
||||
func NewInvalidCredentialError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(401, "InvalidCredentialError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrInvalidCredential], string(ErrInvalidCredential), msg, params...)
|
||||
}
|
||||
|
||||
func NewForbiddenError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(403, "ForbiddenError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrForbidden], string(ErrForbidden), msg, params...)
|
||||
}
|
||||
|
||||
func NewNotFoundError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(404, "NotFoundError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrNotFound], string(ErrNotFound), msg, params...)
|
||||
}
|
||||
|
||||
func NewNotAcceptableError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(406, "NotAcceptableError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrNotAcceptable], string(ErrNotAcceptable), msg, params...)
|
||||
}
|
||||
|
||||
func NewDuplicateNameError(resName string, resId string) *httputils.JSONClientError {
|
||||
msg, err := errorMessage("Duplicate %s %s", resName, resId)
|
||||
return NewJsonClientError(409, "DuplicateNameError", msg, err)
|
||||
msg := "Duplicate name %s %s"
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrDuplicateName], string(ErrDuplicateName), msg, resName, resId)
|
||||
}
|
||||
|
||||
func NewDuplicateIdError(resName string, resId string) *httputils.JSONClientError {
|
||||
msg := "Duplicate ID %s %s"
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrDuplicateId], string(ErrDuplicateId), msg, resName, resId)
|
||||
}
|
||||
|
||||
func NewDuplicateResourceError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params)
|
||||
return NewJsonClientError(409, "DuplicateResourceError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrDuplicateResource], string(ErrDuplicateResource), msg, params...)
|
||||
}
|
||||
|
||||
func NewConflictError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(409, "ConflictError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrConflict], string(ErrConflict), msg, params...)
|
||||
}
|
||||
|
||||
func NewResourceBusyError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(409, "ResourceBusyError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrResourceBusy], string(ErrResourceBusy), msg, params...)
|
||||
}
|
||||
|
||||
func NewRequireLicenseError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(402, "RequireLicenseError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrRequireLicense], string(ErrRequireLicense), msg, params...)
|
||||
}
|
||||
|
||||
func NewTimeoutError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(504, "TimeoutError", msg, err)
|
||||
}
|
||||
|
||||
func NewGeneralError(err error) *httputils.JSONClientError {
|
||||
switch err.(type) {
|
||||
case *httputils.JSONClientError:
|
||||
return err.(*httputils.JSONClientError)
|
||||
default:
|
||||
return NewInternalServerError(err.Error())
|
||||
}
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrTimeout], string(ErrTimeout), msg, params...)
|
||||
}
|
||||
|
||||
func NewProtectedResourceError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(403, "ProtectedResourceError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrProtectedResource], string(ErrProtectedResource), msg, params...)
|
||||
}
|
||||
|
||||
func NewNoProjectError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
msg, err := errorMessage(msg, params...)
|
||||
return NewJsonClientError(403, "NoProjectError", msg, err)
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrNoProject], string(ErrNoProject), msg, params...)
|
||||
}
|
||||
|
||||
func NewServerError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
return httputils.NewJsonClientError(httpErrorCode[errors.ErrServer], string(errors.ErrServer), msg, params...)
|
||||
}
|
||||
|
||||
func NewClientError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
return httputils.NewJsonClientError(httpErrorCode[errors.ErrClient], string(errors.ErrClient), msg, params...)
|
||||
}
|
||||
|
||||
func NewUnclassifiedError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
return httputils.NewJsonClientError(httpErrorCode[errors.ErrUnclassified], string(errors.ErrUnclassified), msg, params)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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 httperrors
|
||||
|
||||
import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
)
|
||||
|
||||
func NewGeneralError(err error) *httputils.JSONClientError {
|
||||
switch nerr := err.(type) {
|
||||
case *httputils.JSONClientError:
|
||||
return nerr
|
||||
case errors.Error:
|
||||
code, ok := httpErrorCode[nerr]
|
||||
if !ok {
|
||||
code = 500
|
||||
}
|
||||
return httputils.NewJsonClientError(code, string(nerr), err.Error())
|
||||
default:
|
||||
root := errors.Cause(err)
|
||||
switch nerr := root.(type) {
|
||||
case *httputils.JSONClientError:
|
||||
nerr.Details = err.Error()
|
||||
return nerr
|
||||
case errors.Error:
|
||||
code, ok := httpErrorCode[nerr]
|
||||
if !ok {
|
||||
code = 500
|
||||
}
|
||||
return httputils.NewJsonClientError(code, string(nerr), err.Error())
|
||||
default:
|
||||
return NewUnclassifiedError(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package httputils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// New a http Json client error
|
||||
// code: http error code, >=400
|
||||
// class: error class
|
||||
// msg: message
|
||||
// params: message format parameters
|
||||
func NewJsonClientError(code int, class string, msg string, params ...interface{}) *JSONClientError {
|
||||
details, err := errorMessage(msg, params...)
|
||||
return &JSONClientError{Code: code, Class: class, Details: details, Data: err}
|
||||
}
|
||||
|
||||
func errorMessage(msgFmt string, params ...interface{}) (string, Error) {
|
||||
fields := make([]string, len(params))
|
||||
for i, v := range params {
|
||||
fields[i] = fmt.Sprint(v)
|
||||
}
|
||||
|
||||
err := Error{
|
||||
Id: msgFmtToTmpl(msgFmt),
|
||||
Fields: fields,
|
||||
}
|
||||
|
||||
msg := msgFmt
|
||||
if len(params) > 0 {
|
||||
msg = fmt.Sprintf(msg, params...)
|
||||
}
|
||||
return msg, err
|
||||
}
|
||||
|
||||
func msgFmtToTmpl(msgFmt string) string {
|
||||
// 将%s %d之类格式化字符串转换成{0}、{1}格式
|
||||
// 注意: 1.不支持复杂类型的转换例如%.2f , %[1]d, % x
|
||||
// 2.原始msgFmt中如果包含{0},{1}形式的字符串同样会引发错误。
|
||||
// 在抛出error msgFmt时应注意避免
|
||||
fmtstr := false
|
||||
lst := []rune(msgFmt)
|
||||
lastIndex := len(lst) - 1
|
||||
temp := bytes.Buffer{}
|
||||
index := 0
|
||||
for i, c := range lst {
|
||||
switch c {
|
||||
case '%':
|
||||
if fmtstr || i == lastIndex {
|
||||
temp.WriteRune(c)
|
||||
fmtstr = false
|
||||
} else {
|
||||
fmtstr = true
|
||||
}
|
||||
case 'v', 'T', 't', 'b', 'c', 'd', 'o', 'q', 'x', 'X', 'U', 'e', 'E', 'f', 'F', 'g', 'G', 's', 'p':
|
||||
if fmtstr {
|
||||
temp.WriteRune('{')
|
||||
temp.WriteString(fmt.Sprintf("%d", index))
|
||||
temp.WriteRune('}')
|
||||
index++
|
||||
fmtstr = false
|
||||
} else {
|
||||
temp.WriteRune(c)
|
||||
}
|
||||
|
||||
default:
|
||||
if fmtstr {
|
||||
temp.WriteRune('%')
|
||||
}
|
||||
temp.WriteRune(c)
|
||||
fmtstr = false
|
||||
}
|
||||
}
|
||||
|
||||
return temp.String()
|
||||
}
|
||||
|
||||
func MsgTmplToFmt(tmpl string) string {
|
||||
return msgTmplToFmt(tmpl)
|
||||
}
|
||||
|
||||
func msgTmplToFmt(tmpl string) string {
|
||||
b := &bytes.Buffer{}
|
||||
for i := 0; i < len(tmpl); {
|
||||
r := tmpl[i]
|
||||
if r != '{' {
|
||||
b.WriteByte(r)
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
j := i + 1
|
||||
for ; j < len(tmpl); j++ {
|
||||
r := tmpl[j]
|
||||
if r < '0' || r > '9' {
|
||||
break
|
||||
}
|
||||
}
|
||||
if j == len(tmpl) {
|
||||
b.WriteString(tmpl[i:])
|
||||
return b.String()
|
||||
}
|
||||
if j > i+1 && tmpl[j] == '}' {
|
||||
b.WriteString("%s")
|
||||
i = j + 1
|
||||
} else {
|
||||
b.WriteString(tmpl[i:j])
|
||||
i = j
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/moul/http2curl"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
"yunion.io/x/pkg/trace"
|
||||
|
||||
@@ -81,6 +82,18 @@ func (e *JSONClientError) Error() string {
|
||||
return jsonutils.Marshal(errMsg).String()
|
||||
}
|
||||
|
||||
func (err *JSONClientError) Cause() error {
|
||||
if len(err.Class) > 0 {
|
||||
return errors.Error(err.Class)
|
||||
} else if err.Code >= 500 {
|
||||
return errors.ErrServer
|
||||
} else if err.Code >= 400 {
|
||||
return errors.ErrClient
|
||||
} else {
|
||||
return errors.ErrUnclassified
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorCode(err error) int {
|
||||
if err == nil {
|
||||
return 0
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SErrorMsg struct {
|
||||
@@ -125,3 +126,18 @@ func TestError(t *testing.T) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorCause(t *testing.T) {
|
||||
err := errors.Error("TestError")
|
||||
jsonError := &JSONClientError{
|
||||
Code: 400,
|
||||
Class: string(err),
|
||||
Details: "detailed test error",
|
||||
}
|
||||
wrapError := errors.Wrap(jsonError, "wrap1")
|
||||
if errors.Cause(wrapError) == err {
|
||||
t.Logf("%s", wrapError)
|
||||
} else {
|
||||
t.Errorf("wrapErro.Cause should be err: %#v != %#v", errors.Cause(wrapError), err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user