...
1package errors
2
3import (
4 "fmt"
5 "github.com/golang/protobuf/proto"
6 "golang.conradwood.net/apis/common"
7 fw "golang.conradwood.net/apis/framework"
8 goe "golang.conradwood.net/apis/goeasyops"
9 "google.golang.org/grpc/status"
10 proto2 "google.golang.org/protobuf/proto"
11 "google.golang.org/protobuf/protoadapt"
12 "strings"
13)
14
15// extracts the PRIVATE and possibly SENSITIVE debug error message from a string
16// obsolete - use errors.ErrorString(err)
17// the reason this is so convoluted with different types, is that different versions of grpc
18// encapsulate status details in different messages.
19func ErrorString(err error) string {
20 st := status.Convert(err)
21 s := "[STATUS] "
22 deli := ""
23 var cstatus *common.Status
24 var gel *goe.GRPCErrorList
25 for _, a := range st.Details() {
26 unknown := true
27
28 proto2m := a.(proto2.Message)
29 msgname := proto2.MessageName(proto2m)
30 // msg := proto2m.ProtoReflect()
31 pv1 := protoadapt.MessageV1Of(proto2m)
32 //fmt.Printf("Proto2 (%s): %#v %v %v\n", msgname, proto2m, msg, pv1)
33 if msgname == "goeasyops.GRPCErrorList" {
34 xgel, ok := pv1.(*goe.GRPCErrorList)
35 if ok {
36 gel = xgel
37 s = s + deli + ge2string(xgel)
38 continue
39 }
40 } else if msgname == "common.Status" {
41 st, ok := pv1.(*common.Status)
42 if ok {
43 cstatus = st
44 continue
45 }
46 }
47
48 fmd, ok := a.(*fw.FrameworkMessageDetail)
49 if ok {
50 unknown = false
51 s = s + deli + fmd2string(fmd)
52 }
53
54 ge, ok := a.(*goe.GRPCErrorList)
55 if unknown && ok {
56 unknown = false
57 s = s + deli + ge2string(ge)
58 }
59
60 ge2, ok := a.(goe.GRPCErrorList)
61 if unknown && ok {
62 unknown = false
63 s = s + deli + ge2string(&ge2)
64 }
65
66 x, ok := a.(goe.GRPCError)
67 if unknown && ok {
68 unknown = false
69 s = s + deli + fmt.Sprintf("CALLTRACE: %v", x)
70 }
71
72 x2, ok := a.(*fw.CallTrace)
73 if unknown && ok {
74 unknown = false
75 s = s + deli + fmt.Sprintf("CALLTRACE: %v", x2)
76 }
77
78 proto, ok := a.(proto.Message)
79 if unknown && ok {
80 unknown = false
81 s = s + deli + "proto:" + proto.String()
82 }
83
84 deli = "->"
85
86 }
87 s = s + ": " + st.Message() + " [/STATUS]"
88 if cstatus == nil || gel == nil {
89 return s
90 }
91 s = fmt.Sprintf("%d(%s): ", cstatus.ErrorCode, cstatus.ErrorDescription) + ge2string(gel)
92 return s
93
94}
95
96func fmd2string(fmd *fw.FrameworkMessageDetail) string {
97 s := ""
98 for _, ct := range fmd.CallTraces {
99 if ct.Service != "" {
100 spl := strings.SplitN(ct.Service, ".", 2)
101 sn := ct.Service
102 if len(spl) == 2 {
103 sn = spl[1]
104 }
105 s = fmt.Sprintf("(1 %s.%s)", sn, ct.Method)
106 } else {
107 s = fmt.Sprintf("(2 %s)", ct.Message)
108 }
109 }
110 return s
111}
112
113func ge2string(fmd *goe.GRPCErrorList) string {
114 s := ""
115 for _, ct := range fmd.Errors {
116 if ct.ServiceName != "" {
117 spl := strings.SplitN(ct.ServiceName, ".", 2)
118 sn := ct.ServiceName
119 if len(spl) == 2 {
120 sn = spl[1]
121 }
122 s = fmt.Sprintf("(3 %s.%s)", sn, ct.MethodName)
123 } else {
124 s = fmt.Sprintf("(4 %s)", ct.LogMessage)
125 }
126 }
127 return s
128}
View as plain text