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
|
||
}
|