536 lines
15 KiB
Go
536 lines
15 KiB
Go
package errs
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"strings"
|
||
|
||
"code.30cm.net/digimon/library-go/errs/code"
|
||
"github.com/zeromicro/go-zero/core/logx"
|
||
"google.golang.org/grpc/status"
|
||
)
|
||
|
||
const (
|
||
defaultDetailCode = 00
|
||
)
|
||
|
||
func newBuiltinGRPCErr(scope, detail uint32, msg string) *LibError {
|
||
return &LibError{
|
||
category: code.CatGRPC,
|
||
code: detail,
|
||
scope: scope,
|
||
msg: msg,
|
||
}
|
||
}
|
||
|
||
// FromError tries to let error as Err
|
||
// it supports to unwrap error that has Error
|
||
// return nil if failed to transfer
|
||
func FromError(err error) *LibError {
|
||
if err == nil {
|
||
return nil
|
||
}
|
||
|
||
var e *LibError
|
||
if errors.As(err, &e) {
|
||
return e
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// FromCode parses code as following 7 碼
|
||
// Decimal: 1200314
|
||
// 12 represents Scope
|
||
// 003 represents Category
|
||
// 14 represents Detail error code
|
||
func FromCode(code uint32) *LibError {
|
||
// 獲取 scope,前兩位數
|
||
scope := code / 100000
|
||
|
||
// 獲取 detail,最後兩位數
|
||
detail := code % 100
|
||
|
||
// 獲取 category,中間三位數
|
||
category := (code / 100) % 1000
|
||
|
||
return &LibError{
|
||
category: category * 100, // category 放大為三位數的整百數
|
||
code: category*100 + detail, // 重構完整的 code
|
||
scope: scope,
|
||
msg: "",
|
||
}
|
||
}
|
||
|
||
// FromGRPCError transfer error to Err
|
||
// useful for gRPC client
|
||
func FromGRPCError(err error) *LibError {
|
||
s, _ := status.FromError(err)
|
||
e := FromCode(uint32(s.Code()))
|
||
e.msg = s.Message()
|
||
|
||
// For GRPC built-in code
|
||
if e.Scope() == code.Unset && e.Category() == 0 && e.Code() != code.OK {
|
||
e = newBuiltinGRPCErr(Scope, e.Code(), s.Message())
|
||
}
|
||
|
||
return e
|
||
}
|
||
|
||
/*** System ***/
|
||
|
||
// SystemTimeoutError xxx6300 returns Error 系統超時
|
||
func SystemTimeoutError(s ...string) *LibError {
|
||
return NewError(Scope, code.SystemTimeoutError, defaultDetailCode, fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// SystemTimeoutErrorL logs error message and returns Err
|
||
func SystemTimeoutErrorL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := SystemTimeoutError(s...)
|
||
if filed != nil {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// SystemInternalError xxx6100 returns Err struct
|
||
func SystemInternalError(s ...string) *LibError {
|
||
return NewError(Scope, code.SystemInternalError, defaultDetailCode, fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// SystemInternalErrorL logs error message and returns Err
|
||
func SystemInternalErrorL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := SystemInternalError(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
/*** CatInput ***/
|
||
|
||
// InvalidFormat returns Err struct
|
||
func InvalidFormat(s ...string) *LibError {
|
||
return NewError(Scope, code.InvalidFormat, defaultDetailCode, fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// InvalidFormatL logs error message and returns Err
|
||
func InvalidFormatL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := InvalidFormat(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// InvalidRange returns Err struct
|
||
func InvalidRange(s ...string) *LibError {
|
||
return NewError(Scope, code.InvalidRange, defaultDetailCode, fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// InvalidRangeL logs error message and returns Err
|
||
func InvalidRangeL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := InvalidRange(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// NotValidImplementation returns Err struct
|
||
func NotValidImplementation(s ...string) *LibError {
|
||
return NewError(Scope, code.NotValidImplementation, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// NotValidImplementationL logs error message and returns Err
|
||
func NotValidImplementationL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := NotValidImplementation(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
/*** CatDB ***/
|
||
|
||
// DBError returns Err
|
||
func DBError(s ...string) *LibError {
|
||
return NewError(Scope, code.DBError, defaultDetailCode, fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// DBErrorL logs error message and returns Err
|
||
func DBErrorL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := DBError(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
return e
|
||
}
|
||
|
||
// DBDataConvert returns Err
|
||
func DBDataConvert(s ...string) *LibError {
|
||
return NewError(Scope, code.DBDataConvert, defaultDetailCode, fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// DBDataConvertL logs error message and returns Err
|
||
func DBDataConvertL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := DBDataConvert(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// DBDuplicate returns Err
|
||
func DBDuplicate(s ...string) *LibError {
|
||
return NewError(Scope, code.DBDuplicate, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// DBDuplicateL logs error message and returns Err
|
||
func DBDuplicateL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := DBDuplicate(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
/*** CatResource ***/
|
||
|
||
// ResourceNotFound returns Err and logging
|
||
func ResourceNotFound(s ...string) *LibError {
|
||
return NewError(Scope, code.ResourceNotFound, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// ResourceNotFoundL logs error message and returns Err
|
||
func ResourceNotFoundL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := ResourceNotFound(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// InvalidResourceFormat returns Err
|
||
func InvalidResourceFormat(s ...string) *LibError {
|
||
return NewError(Scope, code.InvalidResourceFormat, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// InvalidResourceFormatL logs error message and returns Err
|
||
func InvalidResourceFormatL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := InvalidResourceFormat(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// InvalidResourceState returns status not correct.
|
||
// for example: company should be destroy, agent should be no-sensor/fail-install ...
|
||
func InvalidResourceState(s ...string) *LibError {
|
||
return NewError(Scope, code.InvalidResourceState, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// InvalidResourceStateL logs error message and returns status not correct.
|
||
func InvalidResourceStateL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := InvalidResourceState(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
func ResourceInsufficient(s ...string) *LibError {
|
||
return NewError(Scope, code.ResourceInsufficient, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
func ResourceInsufficientL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := ResourceInsufficient(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// InsufficientPermission returns Err
|
||
func InsufficientPermission(s ...string) *LibError {
|
||
return NewError(Scope, code.InsufficientPermission,
|
||
defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// InsufficientPermissionL returns Err and log
|
||
func InsufficientPermissionL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := InsufficientPermission(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// ResourceAlreadyExist returns Err
|
||
func ResourceAlreadyExist(s ...string) *LibError {
|
||
return NewError(Scope, code.ResourceAlreadyExist, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// ResourceAlreadyExistL logs error message and returns Err
|
||
func ResourceAlreadyExistL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := ResourceAlreadyExist(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// InvalidMeasurementID returns Err
|
||
func InvalidMeasurementID(s ...string) *LibError {
|
||
return NewError(Scope, code.InvalidMeasurementID, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// InvalidMeasurementIDL logs error message and returns Err
|
||
func InvalidMeasurementIDL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := InvalidMeasurementID(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// ResourceExpired returns Err
|
||
func ResourceExpired(s ...string) *LibError {
|
||
return NewError(Scope, code.ResourceExpired,
|
||
defaultDetailCode, fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// ResourceExpiredL logs error message and returns Err
|
||
func ResourceExpiredL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := ResourceExpired(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// ResourceMigrated returns Err
|
||
func ResourceMigrated(s ...string) *LibError {
|
||
return NewError(Scope, code.ResourceMigrated, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// ResourceMigratedL logs error message and returns Err
|
||
func ResourceMigratedL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := ResourceMigrated(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// InsufficientQuota returns Err
|
||
func InsufficientQuota(s ...string) *LibError {
|
||
return NewError(Scope, code.InsufficientQuota, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// InsufficientQuotaL logs error message and returns Err
|
||
func InsufficientQuotaL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := InsufficientQuota(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
/*** CatAuth ***/
|
||
|
||
// Unauthorized returns Err
|
||
func Unauthorized(s ...string) *LibError {
|
||
return NewError(Scope, code.Unauthorized, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// UnauthorizedL logs error message and returns Err
|
||
func UnauthorizedL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := Unauthorized(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// AuthExpired returns Err
|
||
func AuthExpired(s ...string) *LibError {
|
||
return NewError(Scope, code.AuthExpired, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// AuthExpiredL logs error message and returns Err
|
||
func AuthExpiredL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := AuthExpired(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// InvalidPosixTime returns Err
|
||
func InvalidPosixTime(s ...string) *LibError {
|
||
return NewError(Scope, code.InvalidPosixTime, defaultDetailCode,
|
||
fmt.Sprintf("i%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// InvalidPosixTimeL logs error message and returns Err
|
||
func InvalidPosixTimeL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := InvalidPosixTime(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// SigAndPayloadNotMatched returns Err
|
||
func SigAndPayloadNotMatched(s ...string) *LibError {
|
||
return NewError(Scope, code.SigAndPayloadNotMatched, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// SigAndPayloadNotMatchedL logs error message and returns Err
|
||
func SigAndPayloadNotMatchedL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := SigAndPayloadNotMatched(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// Forbidden returns Err
|
||
func Forbidden(s ...string) *LibError {
|
||
return NewError(Scope, code.Forbidden, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// ForbiddenL logs error message and returns Err
|
||
func ForbiddenL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := Forbidden(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// IsAuthUnauthorizedError check the err is unauthorized error
|
||
func IsAuthUnauthorizedError(err *LibError) bool {
|
||
switch err.Code() / 100 {
|
||
case code.Unauthorized, code.AuthExpired, code.InvalidPosixTime,
|
||
code.SigAndPayloadNotMatched, code.Forbidden,
|
||
code.InvalidFormat, code.ResourceNotFound:
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
/*** CatPubSub ***/
|
||
|
||
// Publish returns Err
|
||
func Publish(s ...string) *LibError {
|
||
return NewError(Scope, code.Publish, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// PublishL logs error message and returns Err
|
||
func PublishL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := Publish(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
return e
|
||
}
|
||
|
||
// Consume returns Err
|
||
func Consume(s ...string) *LibError {
|
||
return NewError(Scope, code.Consume, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
func ConsumeL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := Consume(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|
||
|
||
// MsgSizeTooLarge returns Err
|
||
func MsgSizeTooLarge(s ...string) *LibError {
|
||
return NewError(Scope, code.MsgSizeTooLarge, defaultDetailCode,
|
||
fmt.Sprintf("%s", strings.Join(s, " ")))
|
||
}
|
||
|
||
// MsgSizeTooLargeL logs error message and returns Err
|
||
func MsgSizeTooLargeL(l logx.Logger, filed []logx.LogField, s ...string) *LibError {
|
||
e := MsgSizeTooLarge(s...)
|
||
if filed != nil || len(filed) >= 0 {
|
||
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||
}
|
||
l.WithCallerSkip(1).Error(e.Error())
|
||
|
||
return e
|
||
}
|