You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.2 KiB
97 lines
2.2 KiB
package ecode
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/bilibili/kratos/pkg/ecode/types"
|
|
"github.com/golang/protobuf/proto"
|
|
"github.com/golang/protobuf/ptypes"
|
|
)
|
|
|
|
// Error new status with code and message
|
|
func Error(code Code, message string) *Status {
|
|
return &Status{s: &types.Status{Code: int32(code.Code()), Message: message}}
|
|
}
|
|
|
|
// Errorf new status with code and message
|
|
func Errorf(code Code, format string, args ...interface{}) *Status {
|
|
return Error(code, fmt.Sprintf(format, args...))
|
|
}
|
|
|
|
var _ Codes = &Status{}
|
|
|
|
// Status statusError is an alias of a status proto
|
|
// implement ecode.Codes
|
|
type Status struct {
|
|
s *types.Status
|
|
}
|
|
|
|
// Error implement error
|
|
func (s *Status) Error() string {
|
|
return s.Message()
|
|
}
|
|
|
|
// Code return error code
|
|
func (s *Status) Code() int {
|
|
return int(s.s.Code)
|
|
}
|
|
|
|
// Message return error message for developer
|
|
func (s *Status) Message() string {
|
|
if s.s.Message == "" {
|
|
return strconv.Itoa(int(s.s.Code))
|
|
}
|
|
return s.s.Message
|
|
}
|
|
|
|
// Details return error details
|
|
func (s *Status) Details() []interface{} {
|
|
if s == nil || s.s == nil {
|
|
return nil
|
|
}
|
|
details := make([]interface{}, 0, len(s.s.Details))
|
|
for _, any := range s.s.Details {
|
|
detail := &ptypes.DynamicAny{}
|
|
if err := ptypes.UnmarshalAny(any, detail); err != nil {
|
|
details = append(details, err)
|
|
continue
|
|
}
|
|
details = append(details, detail.Message)
|
|
}
|
|
return details
|
|
}
|
|
|
|
// WithDetails WithDetails
|
|
func (s *Status) WithDetails(pbs ...proto.Message) (*Status, error) {
|
|
for _, pb := range pbs {
|
|
anyMsg, err := ptypes.MarshalAny(pb)
|
|
if err != nil {
|
|
return s, err
|
|
}
|
|
s.s.Details = append(s.s.Details, anyMsg)
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
// Proto return origin protobuf message
|
|
func (s *Status) Proto() *types.Status {
|
|
return s.s
|
|
}
|
|
|
|
// FromCode create status from ecode
|
|
func FromCode(code Code) *Status {
|
|
return &Status{s: &types.Status{Code: int32(code)}}
|
|
}
|
|
|
|
// FromProto new status from grpc detail
|
|
func FromProto(pbMsg proto.Message) Codes {
|
|
if msg, ok := pbMsg.(*types.Status); ok {
|
|
if msg.Message == "" {
|
|
// NOTE: if message is empty convert to pure Code, will get message from config center.
|
|
return Code(msg.Code)
|
|
}
|
|
return &Status{s: msg}
|
|
}
|
|
return Errorf(ServerErr, "invalid proto message get %v", pbMsg)
|
|
}
|
|
|