-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy patherrors.go
97 lines (84 loc) · 1.96 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
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
package opslevel
import (
"errors"
"fmt"
"strings"
"github.com/hasura/go-graphql-client"
)
type ErrorCode int
const (
ErrorUnknown ErrorCode = iota
ErrorRequestError
ErrorAPIError
ErrorResourceNotFound
)
type ClientError struct {
error
ErrorCode ErrorCode
}
func NewClientError(code ErrorCode, err error) error {
return &ClientError{
error: err,
ErrorCode: code,
}
}
func HandleErrors(opts ...any) error {
output := (error)(nil)
for _, opt := range opts {
switch v := opt.(type) {
case error:
if !IsOpsLevelApiError(v) {
output = errors.Join(output, NewClientError(ErrorRequestError, v))
} else {
output = errors.Join(output, v)
}
case []Error:
output = errors.Join(output, HasAPIErrors(v))
}
}
return output
}
func HasAPIErrors(errs []Error) error {
if len(errs) == 0 {
return nil
}
message := "OpsLevel API Errors:"
for _, e := range errs {
if len(e.Path) == 1 && e.Path[0] == "base" {
e.Path[0] = ""
}
message += fmt.Sprintf("\n\t- '%s' %s", strings.Join(e.Path, "."), e.Message)
}
return NewClientError(ErrorAPIError, errors.New(message))
}
func IsResourceFound(resource any) error {
// TODO: Also Check if ID is valid somehow `.Id == ""`
if resource == nil {
return NewClientError(ErrorResourceNotFound, fmt.Errorf("resource '%T' not found", resource))
}
if casted, ok := resource.(Identifiable); ok && casted.GetID() == "" {
return NewClientError(ErrorResourceNotFound, fmt.Errorf("resource '%T' not found", resource))
}
return nil
}
func ErrIs(err error, code ErrorCode) bool {
var clientErr *ClientError
if errors.As(err, &clientErr) {
if clientErr.ErrorCode == code {
return true
}
}
return false
}
// IsOpsLevelApiError checks if the error is returned by OpsLevel's API
func IsOpsLevelApiError(err error) bool {
if _, ok := err.(graphql.Errors); !ok {
return false
}
for _, hasuraErr := range err.(graphql.Errors) {
if len(hasuraErr.Path) > 0 {
return true
}
}
return false
}