@@ -127,14 +127,14 @@ func (datasource *Datasource) query(ctx context.Context, pCtx backend.PluginCont
127127 ops , err := datasource .ops ()
128128 if err != nil {
129129 log .DefaultLogger .Error (err .Error ())
130- return backend .ErrDataResponse (backend .StatusBadRequest , fmt .Sprintf ("Ops eval failure: %v" , err .Error ()))
130+ return backend .ErrDataResponse (backend .StatusBadRequest , fmt .Sprintf ("Ops failure: %v" , err .Error ()))
131131 }
132132 grid = ops
133133 case "eval" :
134134 eval , err := datasource .eval (model .Eval , variables )
135135 if err != nil {
136136 log .DefaultLogger .Error (err .Error ())
137- return backend .ErrDataResponse (backend .StatusBadRequest , fmt .Sprintf ("Axon eval failure: %v" , err .Error ()))
137+ return backend .ErrDataResponse (backend .StatusBadRequest , fmt .Sprintf ("Eval failure: %v" , err .Error ()))
138138 }
139139 grid = eval
140140 case "hisRead" :
@@ -193,54 +193,69 @@ func (datasource *Datasource) CheckHealth(_ context.Context, req *backend.CheckH
193193}
194194
195195func (datasource * Datasource ) ops () (haystack.Grid , error ) {
196- result , err := datasource .client .Ops ()
197- // If the error is a 404, try to reconnect and try again
198- switch error := err .(type ) {
199- case client.HTTPError :
200- if error .Code == 404 {
201- datasource .client .Open ()
196+ return datasource .withRetry (
197+ func () (haystack.Grid , error ) {
202198 return datasource .client .Ops ()
203- } else {
204- return result , err
205- }
206- default :
207- return result , err
208- }
199+ },
200+ )
209201}
210202
211203func (datasource * Datasource ) eval (expr string , variables map [string ]string ) (haystack.Grid , error ) {
212204 for name , val := range variables {
213205 expr = strings .ReplaceAll (expr , name , val )
214206 }
215- result , err := datasource .client .Eval (expr )
216- // If the error is a 404, try to reconnect and try again
217- switch error := err .(type ) {
218- case client.HTTPError :
219- if error .Code == 404 {
220- datasource .client .Open ()
207+
208+ return datasource .withRetry (
209+ func () (haystack.Grid , error ) {
221210 return datasource .client .Eval (expr )
222- } else {
223- return result , err
224- }
225- default :
226- return result , err
227- }
211+ },
212+ )
228213}
229214
230215func (datasource * Datasource ) hisRead (id string , timeRange backend.TimeRange ) (haystack.Grid , error ) {
231216 ref := haystack .NewRef (id , "" )
232217 start := haystack .NewDateTimeFromGo (timeRange .From .UTC ())
233218 end := haystack .NewDateTimeFromGo (timeRange .To .UTC ())
234- return datasource .client .HisReadAbsDateTime (ref , start , end )
219+
220+ return datasource .withRetry (
221+ func () (haystack.Grid , error ) {
222+ return datasource .client .HisReadAbsDateTime (ref , start , end )
223+ },
224+ )
235225}
236226
237227func (datasource * Datasource ) read (filter string , variables map [string ]string ) (haystack.Grid , error ) {
238228 for name , val := range variables {
239229 filter = strings .ReplaceAll (filter , name , val )
240230 }
241- return datasource .client .Read (filter )
231+
232+ return datasource .withRetry (
233+ func () (haystack.Grid , error ) {
234+ return datasource .client .Read (filter )
235+ },
236+ )
237+ }
238+
239+ // withRetry will retry the given operation if it fails with a 403 or 404 error
240+ func (datasource * Datasource ) withRetry (
241+ operation func () (haystack.Grid , error ),
242+ ) (haystack.Grid , error ) {
243+ result , err := operation ()
244+ // If the error is a 403 or 404, try to reconnect and try again
245+ switch error := err .(type ) {
246+ case client.HTTPError :
247+ if error .Code == 404 || error .Code == 403 {
248+ datasource .client .Open ()
249+ return operation ()
250+ } else {
251+ return result , err
252+ }
253+ default :
254+ return result , err
255+ }
242256}
243257
258+ // dataFrameFromGrid converts a haystack grid to a Grafana data frame
244259func dataFrameFromGrid (grid haystack.Grid ) (* data.Frame , error ) {
245260 fields := []* data.Field {}
246261
@@ -370,6 +385,7 @@ func dataFrameFromGrid(grid haystack.Grid) (*data.Frame, error) {
370385
371386type colType int
372387
388+ // colType represents the type of a column in a haystack grid
373389const (
374390 none colType = iota
375391 dateTime
0 commit comments