hyapp-server/pkg/xerr/catalog.go

135 lines
8.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package xerr
import "google.golang.org/grpc/codes"
const (
httpStatusBadRequest = 400
httpStatusUnauthorized = 401
httpStatusForbidden = 403
httpStatusNotFound = 404
httpStatusConflict = 409
httpStatusInternalServerError = 500
httpStatusBadGateway = 502
)
// Spec 是错误码注册表中的一条稳定契约。
// GRPCCode 是服务间传输语义PublicCode/PublicMessage 是 gateway 对 App 暴露的 envelope。
type Spec struct {
GRPCCode codes.Code
HTTPStatus int
PublicCode string
PublicMessage string
Retryable bool
}
var catalog = map[Code]Spec{
InvalidArgument: spec(codes.InvalidArgument, httpStatusBadRequest, InvalidArgument, "invalid argument"),
NotFound: spec(codes.NotFound, httpStatusNotFound, NotFound, "not found"),
Conflict: spec(codes.FailedPrecondition, httpStatusConflict, Conflict, "conflict"),
RoomClosed: spec(codes.FailedPrecondition, httpStatusConflict, RoomClosed, "room closed"),
Unauthorized: spec(codes.Unauthenticated, httpStatusUnauthorized, Unauthorized, "unauthorized"),
PermissionDenied: spec(codes.PermissionDenied, httpStatusForbidden, PermissionDenied, "permission denied"),
ProfileRequired: spec(codes.PermissionDenied, httpStatusForbidden, ProfileRequired, "profile required"),
Unavailable: {
GRPCCode: codes.Unavailable,
HTTPStatus: httpStatusBadGateway,
PublicCode: "UPSTREAM_ERROR",
PublicMessage: "upstream service error",
Retryable: true,
},
Internal: spec(codes.Internal, httpStatusInternalServerError, Internal, "internal error"),
AuthFailed: spec(codes.Unauthenticated, httpStatusUnauthorized, AuthFailed, "authentication failed"),
AuthLoginBlocked: spec(codes.PermissionDenied, httpStatusForbidden, AuthLoginBlocked, "login blocked"),
PasswordAlreadySet: spec(codes.AlreadyExists, httpStatusConflict, PasswordAlreadySet, "conflict"),
UserDisabled: spec(codes.PermissionDenied, httpStatusForbidden, UserDisabled, "permission denied"),
SessionExpired: spec(codes.Unauthenticated, httpStatusUnauthorized, SessionExpired, "unauthorized"),
SessionRevoked: spec(codes.Unauthenticated, httpStatusUnauthorized, SessionRevoked, "unauthorized"),
DisplayUserIDInvalid: spec(codes.InvalidArgument, httpStatusBadRequest, DisplayUserIDInvalid, "invalid argument"),
DisplayUserIDExists: spec(codes.AlreadyExists, httpStatusConflict, DisplayUserIDExists, "conflict"),
DisplayUserIDCooldown: spec(codes.FailedPrecondition, httpStatusConflict, DisplayUserIDCooldown, "conflict"),
DisplayUserIDNotFound: spec(codes.NotFound, httpStatusNotFound, DisplayUserIDNotFound, "not found"),
DisplayUserIDAllocateFailed: spec(codes.Internal, httpStatusInternalServerError, Internal, "internal error"),
DisplayUserIDPrettyNotAvailable: spec(codes.FailedPrecondition, httpStatusConflict, DisplayUserIDPrettyNotAvailable, "conflict"),
DisplayUserIDPrettyActive: spec(codes.FailedPrecondition, httpStatusConflict, DisplayUserIDPrettyActive, "conflict"),
DisplayUserIDLeaseExpired: spec(codes.FailedPrecondition, httpStatusConflict, DisplayUserIDLeaseExpired, "conflict"),
DisplayUserIDPaymentRequired: spec(codes.FailedPrecondition, httpStatusConflict, DisplayUserIDPaymentRequired, "conflict"),
CountryChangeCooldown: spec(codes.FailedPrecondition, httpStatusConflict, CountryChangeCooldown, "country change is cooling down"),
CountryNotFound: spec(codes.NotFound, httpStatusNotFound, CountryNotFound, "not found"),
RegionNotFound: spec(codes.NotFound, httpStatusNotFound, RegionNotFound, "not found"),
RegionCountryConflict: spec(codes.FailedPrecondition, httpStatusConflict, RegionCountryConflict, "conflict"),
RegionDisabled: spec(codes.FailedPrecondition, httpStatusConflict, RegionDisabled, "conflict"),
InvalidInviteCode: spec(codes.InvalidArgument, httpStatusBadRequest, InvalidInviteCode, "invalid argument"),
DeviceAlreadyRegistered: spec(
codes.FailedPrecondition,
httpStatusConflict,
DeviceAlreadyRegistered,
"conflict",
),
InsufficientBalance: spec(codes.FailedPrecondition, httpStatusConflict, InsufficientBalance, "insufficient balance"),
DuplicateBillingCommand: spec(codes.AlreadyExists, httpStatusConflict, DuplicateBillingCommand, "conflict"),
LedgerConflict: spec(codes.Aborted, httpStatusConflict, LedgerConflict, "conflict"),
CoinSellerNotActive: spec(codes.FailedPrecondition, httpStatusConflict, CoinSellerNotActive, "conflict"),
CoinSellerStockTypeInvalid: spec(codes.InvalidArgument, httpStatusBadRequest, CoinSellerStockTypeInvalid, "invalid argument"),
CoinSellerStockAmountInvalid: spec(codes.InvalidArgument, httpStatusBadRequest, CoinSellerStockAmountInvalid, "invalid argument"),
CoinSellerPaymentRefDuplicated: spec(codes.AlreadyExists, httpStatusConflict, CoinSellerPaymentRefDuplicated, "conflict"),
IdempotencyConflict: spec(codes.AlreadyExists, httpStatusConflict, IdempotencyConflict, "conflict"),
VIPLevelNotFound: spec(codes.NotFound, httpStatusNotFound, VIPLevelNotFound, "not found"),
VIPLevelDisabled: spec(codes.FailedPrecondition, httpStatusConflict, VIPLevelDisabled, "conflict"),
VIPDowngradeNotAllowed: spec(codes.FailedPrecondition, httpStatusConflict, VIPDowngradeNotAllowed, "conflict"),
VIPRechargeRequired: spec(codes.FailedPrecondition, httpStatusConflict, VIPRechargeRequired, "conflict"),
RedPacketDisabled: spec(codes.FailedPrecondition, httpStatusConflict, RedPacketDisabled, "conflict"),
RedPacketInvalidAmountTier: spec(codes.InvalidArgument, httpStatusBadRequest, RedPacketInvalidAmountTier, "invalid argument"),
RedPacketInvalidCountTier: spec(codes.InvalidArgument, httpStatusBadRequest, RedPacketInvalidCountTier, "invalid argument"),
RedPacketAmountTooSmall: spec(codes.InvalidArgument, httpStatusBadRequest, RedPacketAmountTooSmall, "invalid argument"),
RedPacketDailyLimitReached: spec(codes.ResourceExhausted, 429, RedPacketDailyLimitReached, "rate limited"),
RedPacketNotOpen: spec(codes.FailedPrecondition, httpStatusConflict, RedPacketNotOpen, "conflict"),
RedPacketExpired: spec(codes.FailedPrecondition, httpStatusConflict, RedPacketExpired, "conflict"),
RedPacketAlreadyClaimed: spec(codes.AlreadyExists, httpStatusConflict, RedPacketAlreadyClaimed, "conflict"),
RedPacketSoldOut: spec(codes.FailedPrecondition, httpStatusConflict, RedPacketSoldOut, "conflict"),
RuleNotActive: spec(codes.FailedPrecondition, httpStatusConflict, RuleNotActive, "conflict"),
EventAlreadyConsumed: spec(codes.AlreadyExists, httpStatusConflict, EventAlreadyConsumed, "conflict"),
RewardPending: spec(codes.FailedPrecondition, httpStatusConflict, RewardPending, "conflict"),
InvalidSection: spec(codes.InvalidArgument, httpStatusBadRequest, InvalidSection, "invalid argument"),
MessageNotFound: spec(codes.NotFound, httpStatusNotFound, MessageNotFound, "not found"),
MessageRecalled: spec(codes.NotFound, httpStatusNotFound, MessageRecalled, "not found"),
PageTokenInvalid: spec(codes.InvalidArgument, httpStatusBadRequest, PageTokenInvalid, "invalid argument"),
RequestConflict: spec(codes.FailedPrecondition, httpStatusConflict, RequestConflict, "conflict"),
ProducerEventConflict: spec(codes.FailedPrecondition, httpStatusConflict, ProducerEventConflict, "conflict"),
}
func spec(grpcCode codes.Code, httpStatus int, publicCode Code, publicMessage string) Spec {
return Spec{
GRPCCode: grpcCode,
HTTPStatus: httpStatus,
PublicCode: string(publicCode),
PublicMessage: publicMessage,
}
}
// SpecOf 返回业务码的注册表项。未知业务码降级为 INTERNAL_ERROR避免泄漏未登记 reason。
func SpecOf(code Code) Spec {
if registered, ok := catalog[code]; ok {
return registered
}
return catalog[Internal]
}
// RegisteredCodes 返回当前注册表中全部业务码,供测试和文档生成使用。
func RegisteredCodes() []Code {
registered := make([]Code, 0, len(catalog))
for code := range catalog {
registered = append(registered, code)
}
return registered
}