@@ -142,6 +142,14 @@ type HTTPError struct {
142142 RequestURL * url.URL
143143 Message string
144144 OAuthScopes string
145+ Errors []HTTPErrorItem
146+ }
147+
148+ type HTTPErrorItem struct {
149+ Message string
150+ Resource string
151+ Field string
152+ Code string
145153}
146154
147155func (err HTTPError ) Error () string {
@@ -153,79 +161,6 @@ func (err HTTPError) Error() string {
153161 return fmt .Sprintf ("HTTP %d (%s)" , err .StatusCode , err .RequestURL )
154162}
155163
156- type MissingScopesError struct {
157- MissingScopes []string
158- }
159-
160- func (e MissingScopesError ) Error () string {
161- var missing []string
162- for _ , s := range e .MissingScopes {
163- missing = append (missing , fmt .Sprintf ("'%s'" , s ))
164- }
165- scopes := strings .Join (missing , ", " )
166-
167- if len (e .MissingScopes ) == 1 {
168- return "missing required scope " + scopes
169- }
170- return "missing required scopes " + scopes
171- }
172-
173- func (c Client ) HasMinimumScopes (hostname string ) error {
174- apiEndpoint := ghinstance .RESTPrefix (hostname )
175-
176- req , err := http .NewRequest ("GET" , apiEndpoint , nil )
177- if err != nil {
178- return err
179- }
180-
181- req .Header .Set ("Content-Type" , "application/json; charset=utf-8" )
182- res , err := c .http .Do (req )
183- if err != nil {
184- return err
185- }
186-
187- defer func () {
188- // Ensure the response body is fully read and closed
189- // before we reconnect, so that we reuse the same TCPconnection.
190- _ , _ = io .Copy (ioutil .Discard , res .Body )
191- res .Body .Close ()
192- }()
193-
194- if res .StatusCode != 200 {
195- return HandleHTTPError (res )
196- }
197-
198- scopesHeader := res .Header .Get ("X-Oauth-Scopes" )
199- if scopesHeader == "" {
200- // if the token reports no scopes, assume that it's an integration token and give up on
201- // detecting its capabilities
202- return nil
203- }
204-
205- search := map [string ]bool {
206- "repo" : false ,
207- "read:org" : false ,
208- "admin:org" : false ,
209- }
210- for _ , s := range strings .Split (scopesHeader , "," ) {
211- search [strings .TrimSpace (s )] = true
212- }
213-
214- var missingScopes []string
215- if ! search ["repo" ] {
216- missingScopes = append (missingScopes , "repo" )
217- }
218-
219- if ! search ["read:org" ] && ! search ["admin:org" ] {
220- missingScopes = append (missingScopes , "read:org" )
221- }
222-
223- if len (missingScopes ) > 0 {
224- return & MissingScopesError {MissingScopes : missingScopes }
225- }
226- return nil
227- }
228-
229164// GraphQL performs a GraphQL request and parses the response
230165func (c Client ) GraphQL (hostname string , query string , variables map [string ]interface {}, data interface {}) error {
231166 reqBody , err := json .Marshal (map [string ]interface {}{"query" : query , "variables" : variables })
@@ -341,22 +276,16 @@ func HandleHTTPError(resp *http.Response) error {
341276 return httpError
342277 }
343278
344- type errorObject struct {
345- Message string
346- Resource string
347- Field string
348- Code string
349- }
350-
351279 messages := []string {parsedBody .Message }
352280 for _ , raw := range parsedBody .Errors {
353281 switch raw [0 ] {
354282 case '"' :
355283 var errString string
356284 _ = json .Unmarshal (raw , & errString )
357285 messages = append (messages , errString )
286+ httpError .Errors = append (httpError .Errors , HTTPErrorItem {Message : errString })
358287 case '{' :
359- var errInfo errorObject
288+ var errInfo HTTPErrorItem
360289 _ = json .Unmarshal (raw , & errInfo )
361290 msg := errInfo .Message
362291 if errInfo .Code != "custom" {
@@ -365,6 +294,7 @@ func HandleHTTPError(resp *http.Response) error {
365294 if msg != "" {
366295 messages = append (messages , msg )
367296 }
297+ httpError .Errors = append (httpError .Errors , errInfo )
368298 }
369299 }
370300 httpError .Message = strings .Join (messages , "\n " )
0 commit comments