forked from go-kratos/kratos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatus.go
103 lines (88 loc) · 2.33 KB
/
status.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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
}
// Equal for compatible.
// Deprecated: please use ecode.EqualError.
func (s *Status) Equal(err error) bool {
return EqualError(s, err)
}
// 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)
}