@@ -38,6 +38,7 @@ import (
38
38
"io"
39
39
"mime/multipart"
40
40
"net/http"
41
+ "strings"
41
42
42
43
"github.com/pkg/errors"
43
44
)
@@ -79,8 +80,14 @@ func (c *Client) logf(format string, args ...interface{}) {
79
80
// Run executes the query and unmarshals the response from the data field
80
81
// into the response object.
81
82
// Pass in a nil response object to skip response parsing.
82
- // If the request fails or the server returns an error, the first error
83
- // will be returned.
83
+ // If the request fails or the server returns an error, the returned error will
84
+ // be of type Errors. Type assert to get the underlying errors:
85
+ // err := client.Run(..)
86
+ // if err != nil {
87
+ // for _, e := range err.(graphql.Errors) {
88
+ // // ..
89
+ // }
90
+ // }
84
91
func (c * Client ) Run (ctx context.Context , req * Request , resp interface {}) error {
85
92
select {
86
93
case <- ctx .Done ():
@@ -144,8 +151,7 @@ func (c *Client) runWithJSON(ctx context.Context, req *Request, resp interface{}
144
151
return errors .Wrap (err , "decoding response" )
145
152
}
146
153
if len (gr .Errors ) > 0 {
147
- // return first error
148
- return gr .Errors [0 ]
154
+ return gr .Errors
149
155
}
150
156
return nil
151
157
}
@@ -215,8 +221,7 @@ func (c *Client) runWithPostFields(ctx context.Context, req *Request, resp inter
215
221
return errors .Wrap (err , "decoding response" )
216
222
}
217
223
if len (gr .Errors ) > 0 {
218
- // return first error
219
- return gr .Errors [0 ]
224
+ return gr .Errors
220
225
}
221
226
return nil
222
227
}
@@ -249,17 +254,51 @@ func ImmediatelyCloseReqBody() ClientOption {
249
254
// modify the behaviour of the Client.
250
255
type ClientOption func (* Client )
251
256
252
- type graphErr struct {
257
+ // Errors contains all the errors that were returned by the GraphQL server.
258
+ type Errors []Error
259
+
260
+ func (ee Errors ) Error () string {
261
+ if len (ee ) == 0 {
262
+ return "no errors"
263
+ }
264
+ errs := make ([]string , len (ee ))
265
+ for i , e := range ee {
266
+ errs [i ] = e .Message
267
+ }
268
+ return "graphql: " + strings .Join (errs , "; " )
269
+ }
270
+
271
+ // An Error contains error information returned by the GraphQL server.
272
+ type Error struct {
273
+ // Message contains the error message.
253
274
Message string
275
+ // Locations contains the locations in the GraphQL document that caused the
276
+ // error if the error can be associated to a particular point in the
277
+ // requested GraphQL document.
278
+ Locations []Location
279
+ // Path contains the key path of the response field which experienced the
280
+ // error. This allows clients to identify whether a nil result is
281
+ // intentional or caused by a runtime error.
282
+ Path []interface {}
283
+ // Extensions may contain additional fields set by the GraphQL service,
284
+ // such as an error code.
285
+ Extensions map [string ]interface {}
286
+ }
287
+
288
+ // A Location is a location in the GraphQL query that resulted in an error.
289
+ // The location may be returned as part of an error response.
290
+ type Location struct {
291
+ Line int
292
+ Column int
254
293
}
255
294
256
- func (e graphErr ) Error () string {
295
+ func (e Error ) Error () string {
257
296
return "graphql: " + e .Message
258
297
}
259
298
260
299
type graphResponse struct {
261
300
Data interface {}
262
- Errors [] graphErr
301
+ Errors Errors
263
302
}
264
303
265
304
// Request is a GraphQL request.
0 commit comments