Skip to content

Commit 1190a92

Browse files
committed
add RateLimitExceededError
1 parent 8a381cb commit 1190a92

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

githubkit/core.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import timedelta, datetime, timezone
12
from types import TracebackType
23
from contextvars import ContextVar
34
from contextlib import contextmanager, asynccontextmanager
@@ -22,7 +23,7 @@
2223
from .response import Response
2324
from .utils import obj_to_jsonable
2425
from .config import Config, get_config
25-
from .exception import RequestError, RequestFailed, RequestTimeout
26+
from .exception import RequestError, RequestFailed, RequestTimeout, RateLimitExceededError
2627
from .auth import BaseAuthStrategy, TokenAuthStrategy, UnauthAuthStrategy
2728
from .typing import (
2829
URLTypes,
@@ -316,6 +317,21 @@ def _check(
316317
if response.is_error:
317318
error_models = error_models or {}
318319
status_code = str(response.status_code)
320+
321+
if response.status_code == 403 and "retry-after" in response.headers:
322+
raise RateLimitExceededError(timedelta(seconds=int(response.headers["retry-after"])), original_message=response.content)
323+
324+
if (
325+
response.status_code in [403, 429]
326+
and "x-ratelimit-remaining" in response.headers
327+
and response.headers["x-ratelimit-remaining"] == "0"
328+
):
329+
retry_after = datetime.fromtimestamp(
330+
int(response.headers["x-ratelimit-reset"]), tz=timezone.utc
331+
) - datetime.now(tz=timezone.utc)
332+
retry_after = max(retry_after, timedelta())
333+
raise RateLimitExceededError(retry_after, original_message=response.content)
334+
319335
error_model = error_models.get(
320336
status_code,
321337
error_models.get(

githubkit/exception.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import timedelta
12
from typing import TYPE_CHECKING
23

34
import httpx
@@ -23,6 +24,20 @@ class RequestError(GitHubException):
2324
"""Simple API request failed with unknown error"""
2425

2526

27+
class RateLimitExceededError(GitHubException):
28+
"""Rate Limit Exceeded"""
29+
30+
def __init__(self, retry_after: timedelta, original_message=""):
31+
self.retry_after = retry_after
32+
self.original_message = original_message
33+
34+
def __str__(self) -> str:
35+
error_message = f"You have exceeded a Github API rate limit. Retry after: {self.retry_after}"
36+
if self.original_message:
37+
error_message += f"\nResponse message from Github:\n{self.original_message}"
38+
return error_message
39+
40+
2641
class RequestTimeout(GitHubException):
2742
"""Simple API request timeout"""
2843

0 commit comments

Comments
 (0)