-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwire.go
144 lines (122 loc) · 4.22 KB
/
wire.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package bricks
import (
"context"
"errors"
"os"
)
const (
ErrCodeCanceled = iota + 1
ErrCodeUnknown
ErrCodeInvalidArgument
ErrCodeDeadlineExceeded
ErrCodeNotFound
ErrCodeAlreadyExists
ErrCodePermissionDenied
ErrCodeResourceExhausted
ErrCodeFailedPrecondition
ErrCodeAborted
ErrCodeOutOfRange
ErrCodeUnimplemented
ErrCodeInternal
ErrCodeUnavailable
ErrCodeDataLoss
ErrCodeUnauthenticated
)
var (
ErrRetryable = errors.New("temporary issue")
ErrUnknown = ErrorWithCode(ErrCodeUnknown, errors.New("unknown error"))
ErrCanceled = errors.Join(ErrRetryable, ErrorWithCode(ErrCodeCanceled, errors.New("operation was canceled")))
// ErrDeadlineExceeded indicates timeout has been reached regardless of operation result.
//
// May result in these http status codes:
// * 408
// * 504
ErrDeadlineExceeded = errors.Join(ErrRetryable,
ErrorWithCode(ErrCodeDeadlineExceeded, errors.New("operation expired before completion")))
// ErrResourceExhausted indicates some resource has been exhausted,
// perhaps a per-user quota (like rate limiting), or perhaps the entire file system is out of space.
// Situations like out-of-memory and server overload, or when a message is larger than the configured maximum size.
//
// May result in these http status codes:
// * 429
// * 507
ErrResourceExhausted = errors.Join(ErrRetryable,
ErrorWithCode(ErrCodeResourceExhausted, errors.New("resource has been exhausted")))
// ----------------------
// Customer-side
// ----------------------
ErrCustomerSide = errors.New("customer-side error")
ErrInvalidArgument = errors.Join(ErrCustomerSide,
ErrorWithCode(ErrCodeInvalidArgument, errors.New("invalid argument")))
ErrUnauthenticated = errors.Join(ErrCustomerSide,
ErrorWithCode(ErrCodeUnauthenticated, errors.New("caller not identified (unauthenticated)")))
ErrPermissionDenied = errors.Join(ErrCustomerSide,
ErrorWithCode(ErrCodePermissionDenied, errors.New("caller identified but permission denied")))
ErrNotFound = errors.Join(ErrCustomerSide,
ErrorWithCode(ErrCodeNotFound, errors.New("requested entity was not found")))
ErrAlreadyExists = errors.Join(ErrCustomerSide,
ErrorWithCode(ErrCodeAlreadyExists, errors.New("entity already exists")))
ErrFailedPrecondition = errors.Join(ErrCustomerSide,
ErrorWithCode(ErrCodeFailedPrecondition, errors.New("failed precondition")))
ErrOutOfRange = errors.Join(ErrCustomerSide,
ErrorWithCode(ErrCodeOutOfRange, errors.New("operation was attempted past the valid range")))
ErrAborted = errors.Join(ErrCustomerSide, ErrorWithCode(ErrCodeAborted, errors.New("operation was aborted")))
ErrDataLoss = errors.Join(ErrCustomerSide,
ErrorWithCode(ErrCodeDataLoss, errors.New("unrecoverable data loss or corruption")))
// ----------------------
// Supplier-side
// ----------------------
ErrSupplierSide = errors.New("supplier-side error")
ErrInternal = errors.Join(ErrRetryable, ErrSupplierSide,
ErrorWithCode(ErrCodeInternal, errors.New("some invariants expected by underlying system has been broken")))
ErrUnimplemented = errors.Join(ErrSupplierSide,
ErrorWithCode(ErrCodeUnimplemented,
errors.New("operation is not implemented or not supported/enabled in this service")))
ErrUnavailable = errors.Join(ErrRetryable, ErrSupplierSide,
ErrorWithCode(ErrCodeUnavailable, errors.New("service is currently unavailable")))
)
type Coded interface {
Code() int
}
func ErrorWithCode(code int, err error) error {
return codedError{
error: err,
code: code,
}
}
type codedError struct {
error
code int
}
func (ce codedError) Code() int {
return ce.code
}
func (ce codedError) Unwrap() error {
return ce.error
}
func ParseError(err, unknown error) error {
if err == nil {
return nil
}
errCat := unknown
if errIsCanceled(err) {
errCat = ErrCanceled
} else if errIsTimeout(err) {
errCat = ErrDeadlineExceeded
}
return errors.Join(errCat, err)
}
func errIsTimeout(err error) bool {
var terr interface{ Timeout() bool }
return (errors.As(err, &terr) && terr.Timeout()) ||
errors.Is(err, os.ErrDeadlineExceeded) ||
errors.Is(err, context.DeadlineExceeded)
}
func errIsCanceled(err error) bool {
return errors.Is(err, context.Canceled)
}
type MessageEnvelope struct {
Id string
Retried uint
Note []byte
}