-
Notifications
You must be signed in to change notification settings - Fork 118
/
errors.go
124 lines (103 loc) · 3.02 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
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 resolve
import (
"bytes"
"fmt"
"strings"
)
type GraphQLError struct {
Message string `json:"message"`
Locations []Location `json:"locations,omitempty"`
// Path is a list of path segments that lead to the error, can be number or string
Path []any `json:"path"`
Extensions map[string]any `json:"extensions,omitempty"`
}
type Location struct {
Line uint32 `json:"line"`
Column uint32 `json:"column"`
}
type SubgraphError struct {
SubgraphName string
Path string
Reason string
ResponseCode int
DownstreamErrors []*GraphQLError
}
func NewSubgraphError(subgraphName, path, reason string, responseCode int) *SubgraphError {
return &SubgraphError{
SubgraphName: subgraphName,
Path: path,
Reason: reason,
ResponseCode: responseCode,
}
}
func (e *SubgraphError) AppendDownstreamError(error *GraphQLError) {
e.DownstreamErrors = append(e.DownstreamErrors, error)
}
func (e *SubgraphError) Error() string {
var bf bytes.Buffer
if e.SubgraphName == "" {
fmt.Fprintf(&bf, "Failed to fetch Subgraph at Path: '%s'", e.Path)
} else {
fmt.Fprintf(&bf, "Failed to fetch from Subgraph '%s' at Path: '%s'", e.SubgraphName, e.Path)
}
if e.Reason != "" {
fmt.Fprintf(&bf, ", Reason: %s.", e.Reason)
} else {
fmt.Fprintf(&bf, ".")
}
if len(e.DownstreamErrors) > 0 {
fmt.Fprintf(&bf, "\n")
fmt.Fprintf(&bf, "Downstream errors:\n")
for i, downstreamError := range e.DownstreamErrors {
extensionCodeErrorString := ""
if downstreamError.Extensions != nil {
if ok := downstreamError.Extensions["code"]; ok != nil {
if code, ok := downstreamError.Extensions["code"].(string); ok {
extensionCodeErrorString = code
}
}
}
if len(downstreamError.Path) > 0 {
builder := strings.Builder{}
for i := range downstreamError.Path {
switch t := downstreamError.Path[i].(type) {
case string:
builder.WriteString(t)
case int:
builder.WriteString(fmt.Sprintf("%d", t))
}
if i < len(downstreamError.Path)-1 {
builder.WriteRune('.')
}
}
path := builder.String()
fmt.Fprintf(&bf, "%d. Subgraph error at Path '%s', Message: %s", i+1, path, downstreamError.Message)
} else {
fmt.Fprintf(&bf, "%d. Subgraph error with Message: %s", i+1, downstreamError.Message)
}
if extensionCodeErrorString != "" {
fmt.Fprintf(&bf, ", Extension Code: %s.", extensionCodeErrorString)
}
fmt.Fprintf(&bf, "\n")
}
}
return bf.String()
}
func NewRateLimitError(subgraphName, path, reason string) *RateLimitError {
return &RateLimitError{
SubgraphName: subgraphName,
Path: path,
Reason: reason,
}
}
type RateLimitError struct {
SubgraphName string
Path string
Reason string
}
func (e *RateLimitError) Error() string {
if e.Reason == "" {
return fmt.Sprintf("Rate limit rejected for Subgraph '%s' at Path '%s'.", e.SubgraphName, e.Path)
}
return fmt.Sprintf("Rate limit rejected for Subgraph '%s' at Path '%s', Reason: %s.", e.SubgraphName, e.Path, e.Reason)
}