@@ -2,144 +2,71 @@ package backend
2
2
3
3
import (
4
4
"context"
5
- "errors"
6
5
"fmt"
7
- "net/http"
6
+
7
+ "github.com/grafana/grafana-plugin-sdk-go/experimental/status"
8
8
)
9
9
10
10
// ErrorSource type defines the source of the error
11
- type ErrorSource string
11
+ type ErrorSource = status. Source
12
12
13
13
const (
14
14
// ErrorSourcePlugin error originates from plugin.
15
- ErrorSourcePlugin ErrorSource = "plugin"
15
+ ErrorSourcePlugin = status . SourcePlugin
16
16
17
17
// ErrorSourceDownstream error originates from downstream service.
18
- ErrorSourceDownstream ErrorSource = "downstream"
18
+ ErrorSourceDownstream = status . SourceDownstream
19
19
20
20
// DefaultErrorSource is the default [ErrorSource] that should be used when it is not explicitly set.
21
- DefaultErrorSource ErrorSource = ErrorSourcePlugin
21
+ DefaultErrorSource = status . SourcePlugin
22
22
)
23
23
24
- func (es ErrorSource ) IsValid () bool {
25
- return es == ErrorSourceDownstream || es == ErrorSourcePlugin
26
- }
27
-
28
- // ErrorSourceFromStatus returns an [ErrorSource] based on provided HTTP status code.
24
+ // ErrorSourceFromHTTPStatus returns an [ErrorSource] based on provided HTTP status code.
29
25
func ErrorSourceFromHTTPStatus (statusCode int ) ErrorSource {
30
- switch statusCode {
31
- case http .StatusMethodNotAllowed ,
32
- http .StatusNotAcceptable ,
33
- http .StatusPreconditionFailed ,
34
- http .StatusRequestEntityTooLarge ,
35
- http .StatusRequestHeaderFieldsTooLarge ,
36
- http .StatusRequestURITooLong ,
37
- http .StatusExpectationFailed ,
38
- http .StatusUpgradeRequired ,
39
- http .StatusRequestedRangeNotSatisfiable ,
40
- http .StatusNotImplemented :
41
- return ErrorSourcePlugin
42
- }
43
-
44
- return ErrorSourceDownstream
45
- }
46
-
47
- type errorWithSourceImpl struct {
48
- source ErrorSource
49
- err error
26
+ return status .SourceFromHTTPStatus (statusCode )
50
27
}
51
28
29
+ // IsDownstreamError return true if provided error is an error with downstream source or
30
+ // a timeout error or a cancelled error.
52
31
func IsDownstreamError (err error ) bool {
53
- e := errorWithSourceImpl {
54
- source : ErrorSourceDownstream ,
55
- }
56
- if errors .Is (err , e ) {
57
- return true
58
- }
59
-
60
- type errorWithSource interface {
61
- ErrorSource () ErrorSource
62
- }
63
-
64
- // nolint:errorlint
65
- if errWithSource , ok := err .(errorWithSource ); ok && errWithSource .ErrorSource () == ErrorSourceDownstream {
66
- return true
67
- }
68
-
69
- if isHTTPTimeoutError (err ) || isCancelledError (err ) {
70
- return true
71
- }
32
+ return status .IsDownstreamError (err )
33
+ }
72
34
73
- return false
35
+ // IsDownstreamError return true if provided error is an error with downstream source or
36
+ // a HTTP timeout error or a cancelled error or a connection reset/refused error or dns not found error.
37
+ func IsDownstreamHTTPError (err error ) bool {
38
+ return status .IsDownstreamHTTPError (err )
74
39
}
75
40
76
41
func DownstreamError (err error ) error {
77
- return errorWithSourceImpl {
78
- source : ErrorSourceDownstream ,
79
- err : err ,
80
- }
42
+ return status .DownstreamError (err )
81
43
}
82
44
83
45
func DownstreamErrorf (format string , a ... any ) error {
84
46
return DownstreamError (fmt .Errorf (format , a ... ))
85
47
}
86
48
87
- func (e errorWithSourceImpl ) ErrorSource () ErrorSource {
88
- return e .source
89
- }
90
-
91
- func (e errorWithSourceImpl ) Error () string {
92
- return fmt .Errorf ("%s error: %w" , e .source , e .err ).Error ()
93
- }
94
-
95
- // Implements the interface used by [errors.Is].
96
- func (e errorWithSourceImpl ) Is (err error ) bool {
97
- if errWithSource , ok := err .(errorWithSourceImpl ); ok {
98
- return errWithSource .ErrorSource () == e .source
99
- }
100
-
101
- return false
102
- }
103
-
104
- func (e errorWithSourceImpl ) Unwrap () error {
105
- return e .err
106
- }
107
-
108
- type errorSourceCtxKey struct {}
109
-
110
- // errorSourceFromContext returns the error source stored in the context.
111
- // If no error source is stored in the context, [DefaultErrorSource] is returned.
112
49
func errorSourceFromContext (ctx context.Context ) ErrorSource {
113
- value , ok := ctx .Value (errorSourceCtxKey {}).(* ErrorSource )
114
- if ok {
115
- return * value
116
- }
117
- return DefaultErrorSource
50
+ return status .SourceFromContext (ctx )
118
51
}
119
52
120
- // initErrorSource initialize the status source for the context.
53
+ // initErrorSource initialize the error source for the context.
121
54
func initErrorSource (ctx context.Context ) context.Context {
122
- s := DefaultErrorSource
123
- return context .WithValue (ctx , errorSourceCtxKey {}, & s )
55
+ return status .InitSource (ctx )
124
56
}
125
57
126
58
// WithErrorSource mutates the provided context by setting the error source to
127
59
// s. If the provided context does not have a error source, the context
128
60
// will not be mutated and an error returned. This means that [initErrorSource]
129
61
// has to be called before this function.
130
62
func WithErrorSource (ctx context.Context , s ErrorSource ) error {
131
- v , ok := ctx .Value (errorSourceCtxKey {}).(* ErrorSource )
132
- if ! ok {
133
- return errors .New ("the provided context does not have a status source" )
134
- }
135
- * v = s
136
- return nil
63
+ return status .WithSource (ctx , s )
137
64
}
138
65
139
66
// WithDownstreamErrorSource mutates the provided context by setting the error source to
140
67
// [ErrorSourceDownstream]. If the provided context does not have a error source, the context
141
68
// will not be mutated and an error returned. This means that [initErrorSource] has to be
142
69
// called before this function.
143
70
func WithDownstreamErrorSource (ctx context.Context ) error {
144
- return WithErrorSource (ctx , ErrorSourceDownstream )
71
+ return status . WithDownstreamSource (ctx )
145
72
}
0 commit comments