@@ -154,6 +154,22 @@ fn github_get(client: &reqwest::Client, url: Url, token: Option<&str>) -> reqwes
154154 if let Some ( token) = token { req. bearer_auth ( token) } else { req }
155155}
156156
157+ async fn ensure_github_success ( resp : reqwest:: Response , action : & str ) -> Result < reqwest:: Response > {
158+ if resp. status ( ) . is_success ( ) {
159+ return Ok ( resp) ;
160+ }
161+
162+ let status = resp. status ( ) ;
163+ let url = resp. url ( ) . clone ( ) ;
164+ warn_on_rate_limit ( "GitHub" , status, action) ;
165+
166+ let mut body = resp. text ( ) . await . unwrap_or_default ( ) ;
167+ if body. len ( ) > 512 {
168+ body. truncate ( 512 ) ;
169+ }
170+ anyhow:: bail!( "GitHub API request failed while {action}: HTTP {status} ({url}): {body}" ) ;
171+ }
172+
157173async fn fetch_github_orgs (
158174 client : & reqwest:: Client ,
159175 api_base : & Url ,
@@ -165,11 +181,11 @@ async fn fetch_github_orgs(
165181 loop {
166182 let mut url = api_base. join ( "organizations" ) . context ( "Failed to build GitHub orgs URL" ) ?;
167183 url. query_pairs_mut ( ) . append_pair ( "per_page" , "100" ) . append_pair ( "page" , & page. to_string ( ) ) ;
168- let resp = github_get ( client , url , token ) . send ( ) . await ? ;
169- if !resp . status ( ) . is_success ( ) {
170- warn_on_rate_limit ( "GitHub" , resp . status ( ) , " listing organizations") ;
171- break ;
172- }
184+ let resp = ensure_github_success (
185+ github_get ( client , url , token ) . send ( ) . await ? ,
186+ " listing organizations",
187+ )
188+ . await ? ;
173189 let page_orgs: Vec < GitHubOrg > = resp. json ( ) . await ?;
174190 if page_orgs. is_empty ( ) {
175191 break ;
@@ -200,11 +216,8 @@ async fn fetch_github_repos(
200216 . append_pair ( "type" , repo_type)
201217 . append_pair ( "sort" , "created" )
202218 . append_pair ( "direction" , "desc" ) ;
203- let resp = github_get ( client, url, token) . send ( ) . await ?;
204- if !resp. status ( ) . is_success ( ) {
205- warn_on_rate_limit ( "GitHub" , resp. status ( ) , action) ;
206- break ;
207- }
219+ let resp =
220+ ensure_github_success ( github_get ( client, url, token) . send ( ) . await ?, action) . await ?;
208221 let page_repos: Vec < GitHubRepo > = resp. json ( ) . await ?;
209222 if page_repos. is_empty ( ) {
210223 break ;
@@ -239,11 +252,11 @@ pub async fn enumerate_contributor_repo_urls(
239252 . join ( & format ! ( "repos/{owner}/{repo}/contributors" ) )
240253 . context ( "Failed to build GitHub contributors URL" ) ?;
241254 url. query_pairs_mut ( ) . append_pair ( "per_page" , "100" ) . append_pair ( "page" , & page. to_string ( ) ) ;
242- let resp = github_get ( & client , url , token . as_deref ( ) ) . send ( ) . await ? ;
243- if !resp . status ( ) . is_success ( ) {
244- warn_on_rate_limit ( "GitHub" , resp . status ( ) , " listing contributors") ;
245- break ;
246- }
255+ let resp = ensure_github_success (
256+ github_get ( & client , url , token . as_deref ( ) ) . send ( ) . await ? ,
257+ " listing contributors",
258+ )
259+ . await ? ;
247260 let contributors: Vec < GitHubContributor > = resp. json ( ) . await ?;
248261 if contributors. is_empty ( ) {
249262 break ;
@@ -296,11 +309,11 @@ pub async fn enumerate_contributor_repo_urls(
296309 . append_pair ( "type" , "all" )
297310 . append_pair ( "sort" , "updated" )
298311 . append_pair ( "direction" , "desc" ) ;
299- let resp = github_get ( & client , url , token . as_deref ( ) ) . send ( ) . await ? ;
300- if !resp . status ( ) . is_success ( ) {
301- warn_on_rate_limit ( "GitHub" , resp . status ( ) , " listing user repositories") ;
302- break ;
303- }
312+ let resp = ensure_github_success (
313+ github_get ( & client , url , token . as_deref ( ) ) . send ( ) . await ? ,
314+ " listing user repositories",
315+ )
316+ . await ? ;
304317 let repos: Vec < GitHubRepo > = resp. json ( ) . await ?;
305318 if repos. is_empty ( ) {
306319 break ;
0 commit comments