-
Notifications
You must be signed in to change notification settings - Fork 0
/
statuserr.go
82 lines (71 loc) · 2.07 KB
/
statuserr.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
package errhandling
import (
"context"
"strings"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/datatrails/go-datatrails-common/logger"
"github.com/datatrails/go-datatrails-common/tracing"
)
// so we dont have to import status package everywhere
type Status = status.Status
func NewStatus(c codes.Code, format string, args ...any) *Status {
return status.Newf(c, format, args...)
}
func StatusError(ctx context.Context, c codes.Code, fmt string, opts ...any) error {
s := NewStatus(c, fmt, opts...)
return StatusWithRequestInfoFromContext(ctx, s).Err()
}
func StatusWithRequestInfoFromContext(ctx context.Context, s *Status) *Status {
log := logger.Sugar.FromContext(ctx)
defer log.Close()
traceID := tracing.TraceIDFromContext(ctx)
if traceID == "" {
log.Infof("no traceID in context")
return s
}
st, err := s.WithDetails(&errdetails.RequestInfo{
RequestId: traceID,
})
if err != nil {
log.Infof("cannot add traceID %s: %v", traceID, err)
return s
}
return st
}
func StatusWithQuotaFailure(ctx context.Context, subject string, label string, name string) *Status {
log := logger.Sugar.FromContext(ctx)
defer log.Close()
s := NewStatus(codes.Unimplemented, "%s %s %s", subject, label, name)
violation := errdetails.QuotaFailure_Violation{
Subject: subject,
Description: " " + label + " " + name,
}
st, err := s.WithDetails(&errdetails.QuotaFailure{
Violations: []*errdetails.QuotaFailure_Violation{
&violation,
},
})
if err != nil {
log.Infof("cannot add quota failure %s: %v", subject, err)
return s
}
return st
}
func IsStatusLimit(err error, label string) bool {
st := status.Convert(err)
for _, detail := range st.Details() {
switch v := detail.(type) {
case *errdetails.QuotaFailure:
for _, violation := range v.GetViolations() {
vals := strings.Split(violation.GetDescription(), " ")
if len(vals) > 1 && vals[1] == label {
logger.Sugar.Debugf("IsStatusLimit: true: status %s %s", label, st)
return true
}
}
}
}
return false
}