backend/pkg/library/errors/from_errors.go

74 lines
1.5 KiB
Go
Raw Normal View History

2025-11-04 09:47:36 +00:00
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
}