Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions src/apify_client/_utils/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

from typing import TYPE_CHECKING

import impit

from apify_client.errors import InvalidResponseBodyError, NotFoundError
from apify_client.errors import NotFoundError

if TYPE_CHECKING:
from apify_client.errors import ApifyApiError
Expand Down Expand Up @@ -33,19 +31,3 @@ def catch_not_found_for_resource_or_throw(exc: ApifyApiError, resource_id: str |
if resource_id is None:
raise exc
catch_not_found_or_throw(exc)


def is_retryable_error(exc: Exception) -> bool:
"""Check if the given error is retryable.

All `impit.HTTPError` subclasses are considered retryable because they represent transport-level failures
(network issues, timeouts, protocol errors, body decoding errors) that are typically transient. HTTP status
code errors are handled separately in `_make_request` based on the response status code, not here.
"""
return isinstance(
exc,
(
InvalidResponseBodyError,
impit.HTTPError,
),
)
35 changes: 2 additions & 33 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,21 @@
from typing import TYPE_CHECKING, Any
from unittest.mock import Mock

import impit
import pytest

from apify_client._models import WebhookCondition, WebhookCreate
from apify_client._resource_clients._resource_client import ResourceClientBase
from apify_client._utils.crypto import create_hmac_signature, create_storage_content_signature, encode_base62
from apify_client._utils.encoding import encode_key_value_store_record_value, encode_webhooks_to_base64
from apify_client._utils.errors import catch_not_found_or_throw, is_retryable_error
from apify_client._utils.errors import catch_not_found_or_throw
from apify_client._utils.http import (
is_compressible_content_type,
response_to_dict,
response_to_list,
to_safe_id,
)
from apify_client._utils.try_import import FailedImport, try_import
from apify_client.errors import ApifyApiError, InvalidResponseBodyError
from apify_client.errors import ApifyApiError

if TYPE_CHECKING:
from apify_client._typeddicts import WebhookRepresentationDict
Expand Down Expand Up @@ -187,36 +186,6 @@ def test_encode_webhooks_to_base64_from_dicts() -> None:
assert result == result_from_models


@pytest.mark.parametrize(
'exc',
[
InvalidResponseBodyError(impit.Response(status_code=200)),
impit.HTTPError('generic http error'),
impit.NetworkError('network error'),
impit.TimeoutException('timeout'),
impit.RemoteProtocolError('remote protocol error'),
impit.ReadError('read error'),
impit.ConnectError('connect error'),
impit.WriteError('write error'),
impit.DecodingError('decoding error'),
],
)
def test__is_retryable_error(exc: Exception) -> None:
assert is_retryable_error(exc) is True


@pytest.mark.parametrize(
'exc',
[
Exception('generic exception'),
ValueError('value error'),
RuntimeError('runtime error'),
],
)
def test__is_not_retryable_error(exc: Exception) -> None:
assert is_retryable_error(exc) is False


@pytest.mark.parametrize(
('status_code', 'error_type', 'should_suppress'),
[
Expand Down
Loading