@@ -13,6 +13,7 @@ import {
1313 AuthenticationErrorReason ,
1414 ProviderRequestClientError ,
1515 ProviderRequestNotFoundError ,
16+ ProviderRequestRateLimitError ,
1617} from '../../errors' ;
1718import { PagedResult , RepositoryVisibility } from '../../git/gitProvider' ;
1819import {
@@ -1748,11 +1749,24 @@ export class GitHubApi implements Disposable {
17481749 throw new ProviderRequestNotFoundError ( ex ) ;
17491750 case 'FORBIDDEN' :
17501751 throw new AuthenticationError ( 'github' , AuthenticationErrorReason . Forbidden , ex ) ;
1752+ case 'RATE_LIMITED' : {
1753+ let resetAt : number | undefined ;
1754+
1755+ const reset = ex . headers ?. [ 'x-ratelimit-reset' ] ;
1756+ if ( reset != null ) {
1757+ resetAt = parseInt ( reset , 10 ) ;
1758+ if ( Number . isNaN ( resetAt ) ) {
1759+ resetAt = undefined ;
1760+ }
1761+ }
1762+
1763+ throw new ProviderRequestRateLimitError ( ex , token , resetAt ) ;
1764+ }
17511765 }
17521766
17531767 void window . showErrorMessage ( `GitHub request failed: ${ ex . errors ?. [ 0 ] ?. message ?? ex . message } ` , 'OK' ) ;
17541768 } else if ( ex instanceof RequestError ) {
1755- this . handleRequestError ( ex ) ;
1769+ this . handleRequestError ( ex , token ) ;
17561770 } else {
17571771 void window . showErrorMessage ( `GitHub request failed: ${ ex . message } ` , 'OK' ) ;
17581772 }
@@ -1770,7 +1784,7 @@ export class GitHubApi implements Disposable {
17701784 return ( await this . octokit ( token ) . request < R > ( route , options ) ) as any ;
17711785 } catch ( ex ) {
17721786 if ( ex instanceof RequestError ) {
1773- this . handleRequestError ( ex ) ;
1787+ this . handleRequestError ( ex , token ) ;
17741788 } else {
17751789 void window . showErrorMessage ( `GitHub request failed: ${ ex . message } ` , 'OK' ) ;
17761790 }
@@ -1779,7 +1793,7 @@ export class GitHubApi implements Disposable {
17791793 }
17801794 }
17811795
1782- private handleRequestError ( ex : RequestError ) : void {
1796+ private handleRequestError ( ex : RequestError , token : string ) : void {
17831797 switch ( ex . status ) {
17841798 case 404 : // Not found
17851799 case 410 : // Gone
@@ -1789,6 +1803,19 @@ export class GitHubApi implements Disposable {
17891803 case 401 : // Unauthorized
17901804 throw new AuthenticationError ( 'github' , AuthenticationErrorReason . Unauthorized , ex ) ;
17911805 case 403 : // Forbidden
1806+ if ( ex . message . includes ( 'rate limit exceeded' ) ) {
1807+ let resetAt : number | undefined ;
1808+
1809+ const reset = ex . response ?. headers ?. [ 'x-ratelimit-reset' ] ;
1810+ if ( reset != null ) {
1811+ resetAt = parseInt ( reset , 10 ) ;
1812+ if ( Number . isNaN ( resetAt ) ) {
1813+ resetAt = undefined ;
1814+ }
1815+ }
1816+
1817+ throw new ProviderRequestRateLimitError ( ex , token , resetAt ) ;
1818+ }
17921819 throw new AuthenticationError ( 'github' , AuthenticationErrorReason . Forbidden , ex ) ;
17931820 case 500 : // Internal Server Error
17941821 if ( ex . response != null ) {
0 commit comments