...
1 package datasource
2
3 import (
4 "fmt"
5 "net/http"
6
7 "github.com/launchdarkly/go-sdk-common/v3/ldlog"
8 "github.com/launchdarkly/go-server-sdk/v6/internal/datakinds"
9 st "github.com/launchdarkly/go-server-sdk/v6/subsystems/ldstoretypes"
10
11 "github.com/launchdarkly/go-jsonstream/v3/jreader"
12 )
13
14 type httpStatusError struct {
15 Message string
16 Code int
17 }
18
19 func (e httpStatusError) Error() string {
20 return e.Message
21 }
22
23
24
25 func isHTTPErrorRecoverable(statusCode int) bool {
26 if statusCode >= 400 && statusCode < 500 {
27 switch statusCode {
28 case 400:
29 return true
30 case 408:
31 return true
32 case 429:
33 return true
34 default:
35 return false
36 }
37 }
38 return true
39 }
40
41 func httpErrorDescription(statusCode int) string {
42 message := ""
43 if statusCode == 401 || statusCode == 403 {
44 message = " (invalid SDK key)"
45 }
46 return fmt.Sprintf("HTTP error %d%s", statusCode, message)
47 }
48
49
50
51 func checkIfErrorIsRecoverableAndLog(
52 loggers ldlog.Loggers,
53 errorDesc, errorContext string,
54 statusCode int,
55 recoverableMessage string,
56 ) bool {
57 if statusCode > 0 && !isHTTPErrorRecoverable(statusCode) {
58 loggers.Errorf("Error %s (giving up permanently): %s", errorContext, errorDesc)
59 return false
60 }
61 loggers.Warnf("Error %s (%s): %s", errorContext, recoverableMessage, errorDesc)
62 return true
63 }
64
65 func checkForHTTPError(statusCode int, url string) error {
66 if statusCode == http.StatusUnauthorized {
67 return httpStatusError{
68 Message: fmt.Sprintf("Invalid SDK key when accessing URL: %s. Verify that your SDK key is correct.", url),
69 Code: statusCode}
70 }
71
72 if statusCode == http.StatusNotFound {
73 return httpStatusError{
74 Message: fmt.Sprintf("Resource not found when accessing URL: %s. Verify that this resource exists.", url),
75 Code: statusCode}
76 }
77
78 if statusCode/100 != 2 {
79 return httpStatusError{
80 Message: fmt.Sprintf("Unexpected response code: %d when accessing URL: %s", statusCode, url),
81 Code: statusCode}
82 }
83 return nil
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 func parseAllStoreDataFromJSONReader(r *jreader.Reader) []st.Collection {
105 var ret []st.Collection
106 for dataObj := r.Object(); dataObj.Next(); {
107 var dataKind datakinds.DataKindInternal
108 switch string(dataObj.Name()) {
109 case "flags":
110 dataKind = datakinds.Features
111 case "segments":
112 dataKind = datakinds.Segments
113 default:
114 continue
115 }
116 coll := st.Collection{Kind: dataKind}
117 for keysToItemsObj := r.Object(); keysToItemsObj.Next(); {
118 key := string(keysToItemsObj.Name())
119 item, err := dataKind.DeserializeFromJSONReader(r)
120 if err == nil {
121 coll.Items = append(coll.Items, st.KeyedItemDescriptor{Key: key, Item: item})
122 }
123 }
124 ret = append(ret, coll)
125 }
126 return ret
127 }
128
View as plain text