-
Notifications
You must be signed in to change notification settings - Fork 0
/
error.go
124 lines (111 loc) · 3.78 KB
/
error.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
package tsc
import (
"encoding/json"
"errors"
"fmt"
)
type ErrorKind int
type ErrorCode int
const (
errorKindUnknown ErrorKind = iota
errorKindTSPService
errorKindSecurityEvent
errorKindKMS
errorKindCrypto
errorKindNetwork
errorKindLocal
)
/**
* These are kinds of errors. Use errors.Is to see if a specific error is of this kind.
*/
var (
ErrKindUnknown = &Error{Kind: errorKindUnknown}
ErrKindTSPService = &Error{Kind: errorKindTSPService}
ErrKindSecurityEvent = &Error{Kind: errorKindSecurityEvent}
ErrKindKMS = &Error{Kind: errorKindKMS}
ErrKindCrypto = &Error{Kind: errorKindCrypto}
ErrKindNetwork = &Error{Kind: errorKindNetwork}
ErrKindLocal = &Error{Kind: errorKindLocal}
)
/**
* These are specific coded errors that can be received from the TSP. Use errors.Is to compare
* against them.
*/
//nolint:gomnd
var (
ErrUnknownError = &Error{Kind: errorKindTSPService, Code: 100}
ErrUnauthorizedRequest = &Error{Kind: errorKindTSPService, Code: 101}
ErrInvalidRequestBody = &Error{Kind: errorKindTSPService, Code: 102}
ErrNoPrimaryKMSConfiguration = &Error{Kind: errorKindKMS, Code: 200}
ErrUnknownTenantOrNoActiveKMSConfigurations = &Error{Kind: errorKindKMS, Code: 201}
ErrKmsConfigurationDisabled = &Error{Kind: errorKindKMS, Code: 202}
ErrInvalidProvidedEDEK = &Error{Kind: errorKindKMS, Code: 203}
ErrKmsWrapFailed = &Error{Kind: errorKindKMS, Code: 204}
ErrKmsUnwrapFailed = &Error{Kind: errorKindKMS, Code: 205}
ErrKmsAuthorizationFailed = &Error{Kind: errorKindKMS, Code: 206}
ErrKmsConfigurationInvalid = &Error{Kind: errorKindKMS, Code: 207}
ErrKmsUnreachable = &Error{Kind: errorKindKMS, Code: 208}
ErrKmsThrottled = &Error{Kind: errorKindKMS, Code: 209}
ErrKmsAccountIssue = &Error{Kind: errorKindKMS, Code: 210}
ErrSecurityEventRejected = &Error{Kind: errorKindSecurityEvent, Code: 301}
)
type Error struct {
Kind ErrorKind
Code ErrorCode
Message string
wrapped error
}
func makeErrorf(kind ErrorKind, format string, a ...interface{}) *Error {
//nolint:goerr113
err := fmt.Errorf(format, a...)
message := err.Error()
wrapped := errors.Unwrap(err)
return &Error{Kind: kind, Message: message, wrapped: wrapped}
}
/**
* setErrorKind is a helper function used when we read the error code from the remote TSP.
* We want to set the error kind from the code, so the user knows how to handle the error.
*/
func (e *Error) setErrorKind() {
switch {
case e.Code < ErrNoPrimaryKMSConfiguration.Code:
e.Kind = ErrKindTSPService.Kind
case e.Code < ErrSecurityEventRejected.Code:
e.Kind = ErrKindKMS.Kind
case e.Code == ErrSecurityEventRejected.Code:
e.Kind = ErrKindSecurityEvent.Kind
}
}
func (e *Error) Error() string {
if e.Code == 0 {
return e.Message
}
return fmt.Sprintf("(code: %d) %v", e.Code, e.Message)
}
func (e *Error) Is(target error) bool {
//nolint:errorlint
t, ok := target.(*Error)
if !ok {
return false
}
return e.Kind == t.Kind && (t.Code == 0 || e.Code == t.Code)
}
// UnmarshalJSON will unmarshal the Code and Message, then set the error's Kind.
//
//nolint:wrapcheck // Because this function is called by json code, it should return a json error.
func (e *Error) UnmarshalJSON(data []byte) error {
rawError := struct {
Code ErrorCode `json:"code"`
Message string `json:"message"`
}{}
if err := json.Unmarshal(data, &rawError); err != nil {
return err
}
e.Message = rawError.Message
e.Code = rawError.Code
e.setErrorKind()
return nil
}
func (e *Error) Unwrap() error {
return e.wrapped
}