diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ff213ae87..76e7b2127 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -36,6 +36,7 @@ Fixes: - Add ``cython.final`` to leaf classes, ensuring that they are not subclassed. - Warn that ``CodecContext.decode()`` is not memory safe in some cases. - Fix ``enumerate_input_devices`` and ``enumerate_output_devices`` raising ``AttributeError`` (:issue:`2264`). +- Map HTTP 429 to ``HTTPTooManyRequestsError`` instead of ``UndefinedError`` (:issue:`2267`). v17.0.1 ------- diff --git a/av/error.py b/av/error.py index 669c8e55a..e6cca095e 100644 --- a/av/error.py +++ b/av/error.py @@ -161,6 +161,7 @@ class HTTPClientError(FFmpegError): ("HTTP_UNAUTHORIZED", -lib.AVERROR_HTTP_UNAUTHORIZED, "HTTPUnauthorizedError", HTTPClientError), ("HTTP_FORBIDDEN", -lib.AVERROR_HTTP_FORBIDDEN, "HTTPForbiddenError", HTTPClientError), ("HTTP_NOT_FOUND", -lib.AVERROR_HTTP_NOT_FOUND, "HTTPNotFoundError", HTTPClientError), + ("HTTP_TOO_MANY_REQUESTS", -lib.AVERROR_HTTP_TOO_MANY_REQUESTS, "HTTPTooManyRequestsError", HTTPClientError), ("HTTP_OTHER_4XX", -lib.AVERROR_HTTP_OTHER_4XX, "HTTPOtherClientError", HTTPClientError), ("HTTP_SERVER_ERROR", -lib.AVERROR_HTTP_SERVER_ERROR, "HTTPServerError", HTTPError), ("PYAV_CALLBACK", c_PYAV_STASHED_ERROR, "PyAVCallbackError", RuntimeError), diff --git a/av/error.pyi b/av/error.pyi index c708a80f6..1191d962f 100644 --- a/av/error.pyi +++ b/av/error.pyi @@ -46,6 +46,7 @@ class HTTPBadRequestError(HTTPClientError): ... class HTTPUnauthorizedError(HTTPClientError): ... class HTTPForbiddenError(HTTPClientError): ... class HTTPNotFoundError(HTTPClientError): ... +class HTTPTooManyRequestsError(HTTPClientError): ... class HTTPOtherClientError(HTTPClientError): ... class HTTPServerError(HTTPError): ... class PyAVCallbackError(FFmpegError, builtins.RuntimeError): ... diff --git a/include/avutil.pxd b/include/avutil.pxd index d7a1fb765..ede8f6fbe 100644 --- a/include/avutil.pxd +++ b/include/avutil.pxd @@ -172,6 +172,7 @@ cdef extern from "libavutil/error.h" nogil: cdef int AVERROR_HTTP_UNAUTHORIZED cdef int AVERROR_HTTP_FORBIDDEN cdef int AVERROR_HTTP_NOT_FOUND + cdef int AVERROR_HTTP_TOO_MANY_REQUESTS cdef int AVERROR_HTTP_OTHER_4XX cdef int AVERROR_HTTP_SERVER_ERROR cdef int AV_ERROR_MAX_STRING_SIZE diff --git a/tests/test_errors.py b/tests/test_errors.py index fdfe0f49d..f4dbf8fbc 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -63,3 +63,16 @@ def test_buffertoosmall() -> None: assert e.errno == BUFFER_TOO_SMALL else: assert False, "No exception raised!" + + +def test_http_too_many_requests() -> None: + """HTTP 429 maps to HTTPTooManyRequestsError, not UndefinedError.""" + + HTTP_TOO_MANY_REQUESTS = av.error.tag_to_code(b"\xf8429") + try: + av.error.err_check(-HTTP_TOO_MANY_REQUESTS) + except av.error.HTTPTooManyRequestsError as e: + assert e.errno == HTTP_TOO_MANY_REQUESTS + assert isinstance(e, av.error.HTTPClientError) + else: + assert False, "No exception raised!"