-
Notifications
You must be signed in to change notification settings - Fork 53
/
errors.go
62 lines (55 loc) · 1.88 KB
/
errors.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
package storage
import (
"github.com/samber/lo"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/runtime/protoimpl"
)
var (
ErrNotFound = status.Error(codes.NotFound, "not found")
ErrAlreadyExists = status.Error(codes.AlreadyExists, "already exists")
ErrConflict = lo.Must(status.New(codes.Aborted, "conflict").WithDetails(ErrDetailsConflict)).Err()
)
var (
ErrDetailsConflict = &errdetails.ErrorInfo{Reason: "CONFLICT"}
ErrDetailsDiscontinuity = &errdetails.ErrorInfo{Reason: "DISCONTINUITY"}
)
// Use this instead of errors.Is(err, ErrNotFound). The implementation of Is()
// for grpc status errors compares the error message, which can result in false negatives.
func IsNotFound(err error) bool {
return status.Code(err) == codes.NotFound
}
// Use this instead of errors.Is(err, ErrAlreadyExists). The implementation of Is()
// for grpc status errors compares the error message, which can result in false negatives.
func IsAlreadyExists(err error) bool {
return status.Code(err) == codes.AlreadyExists
}
// Use this instead of errors.Is(err, ErrConflict). The status code is too
// generic to identify conflict errors, so there are additional details added
// to conflict errors to disambiguate them.
func IsConflict(err error) bool {
stat := status.Convert(err)
if stat.Code() != codes.Aborted {
return false
}
for _, detail := range stat.Details() {
if proto.Equal(protoimpl.X.ProtoMessageV2Of(detail), ErrDetailsConflict) {
return true
}
}
return false
}
func IsDiscontinuity(err error) bool {
stat := status.Convert(err)
if stat.Code() == codes.OK {
return false
}
for _, detail := range stat.Details() {
if info, ok := detail.(*errdetails.ErrorInfo); ok && info.Reason == "DISCONTINUITY" {
return true
}
}
return false
}