74 lines
1.5 KiB
Go
74 lines
1.5 KiB
Go
|
|
package errs
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"errors"
|
|||
|
|
|
|||
|
|
"backend/pkg/library/errors/code"
|
|||
|
|
"google.golang.org/grpc/status"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
func newBuiltinGRPCErr(scope, detail uint32, msg string) *Error {
|
|||
|
|
return &Error{
|
|||
|
|
category: uint32(code.CatGRPC),
|
|||
|
|
detail: 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) *Error {
|
|||
|
|
if err == nil {
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var e *Error
|
|||
|
|
if errors.As(err, &e) {
|
|||
|
|
return e
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// FromCode parses code as following 8 碼
|
|||
|
|
// Decimal: 10201000
|
|||
|
|
// 10 represents Scope
|
|||
|
|
// 201 represents Category
|
|||
|
|
// 000 represents Detail error code
|
|||
|
|
func FromCode(code uint32) *Error {
|
|||
|
|
const CodeMultiplier = 1000000
|
|||
|
|
const SubMultiplier = 1000
|
|||
|
|
// 獲取 scope,前兩位數
|
|||
|
|
scope := code / CodeMultiplier
|
|||
|
|
|
|||
|
|
// 獲取 detail,最後三位數
|
|||
|
|
detail := code % SubMultiplier
|
|||
|
|
|
|||
|
|
// 獲取 category,中間三位數
|
|||
|
|
category := (code / SubMultiplier) % SubMultiplier
|
|||
|
|
|
|||
|
|
return &Error{
|
|||
|
|
category: category,
|
|||
|
|
detail: detail,
|
|||
|
|
scope: scope,
|
|||
|
|
msg: "",
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// FromGRPCError transfer error to Err
|
|||
|
|
// useful for gRPC client
|
|||
|
|
func FromGRPCError(err error) *Error {
|
|||
|
|
s, _ := status.FromError(err)
|
|||
|
|
e := FromCode(uint32(s.Code()))
|
|||
|
|
e.msg = s.Message()
|
|||
|
|
|
|||
|
|
// For GRPC built-in code
|
|||
|
|
if e.Scope() == uint32(code.Unset) && e.Category() == 0 && e.Code() != code.OK {
|
|||
|
|
e = newBuiltinGRPCErr(uint32(Scope), e.detail, s.Message()) // Note: detail is now 3-digit, but built-in codes are small
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return e
|
|||
|
|
}
|