diff --git a/src/linkup/__init__.py b/src/linkup/__init__.py index 09574fe..5ed5a05 100644 --- a/src/linkup/__init__.py +++ b/src/linkup/__init__.py @@ -4,6 +4,7 @@ LinkupBudgetLimitExceededError, LinkupFailedFetchError, LinkupFetchResponseTooLargeError, + LinkupFetchTargetUnreachableError, LinkupFetchUnsupportedContentTypeError, LinkupFetchUrlIsFileError, LinkupInsufficientCreditError, @@ -50,6 +51,7 @@ FetchImageExtraction = LinkupFetchImageExtraction FetchResponse = LinkupFetchResponse FetchResponseTooLargeError = LinkupFetchResponseTooLargeError +FetchTargetUnreachableError = LinkupFetchTargetUnreachableError FetchUnsupportedContentTypeError = LinkupFetchUnsupportedContentTypeError FetchTask = LinkupFetchTask FetchTaskInput = LinkupFetchTaskInput @@ -89,6 +91,7 @@ "FetchImageExtraction", "FetchResponse", "FetchResponseTooLargeError", + "FetchTargetUnreachableError", "FetchTask", "FetchTaskInput", "FetchUnsupportedContentTypeError", @@ -103,6 +106,7 @@ "LinkupFetchImageExtraction", "LinkupFetchResponse", "LinkupFetchResponseTooLargeError", + "LinkupFetchTargetUnreachableError", "LinkupFetchTask", "LinkupFetchTaskInput", "LinkupFetchUnsupportedContentTypeError", diff --git a/src/linkup/_client.py b/src/linkup/_client.py index c6b1647..d7cf223 100644 --- a/src/linkup/_client.py +++ b/src/linkup/_client.py @@ -14,6 +14,7 @@ LinkupBudgetLimitExceededError, LinkupFailedFetchError, LinkupFetchResponseTooLargeError, + LinkupFetchTargetUnreachableError, LinkupFetchUnsupportedContentTypeError, LinkupFetchUrlIsFileError, LinkupInsufficientCreditError, @@ -1023,6 +1024,7 @@ def fetch( LinkupInvalidRequestError: If the provided URL is not valid. LinkupFailedFetchError: If the provided URL is not found or can't be fetched. LinkupFetchResponseTooLargeError: If the fetch response is too large. + LinkupFetchTargetUnreachableError: If the target URL cannot be reached. LinkupFetchUnsupportedContentTypeError: If the URL resolves to an unsupported content type. LinkupTimeoutError: If the request times out. @@ -1073,6 +1075,7 @@ async def async_fetch( LinkupInvalidRequestError: If the provided URL is not valid. LinkupFailedFetchError: If the provided URL is not found or can't be fetched. LinkupFetchResponseTooLargeError: If the fetch response is too large. + LinkupFetchTargetUnreachableError: If the target URL cannot be reached. LinkupFetchUnsupportedContentTypeError: If the URL resolves to an unsupported content type. LinkupTimeoutError: If the request times out. @@ -1316,6 +1319,12 @@ def _raise_linkup_error(self, response: httpx.Response) -> None: "The provided URL's response is too large to be processed.\n" f"Original error message: {error_msg}." ) + if code == "FETCH_TARGET_UNREACHABLE": + raise LinkupFetchTargetUnreachableError( + "The Linkup API returned a fetch target unreachable error (400). " + "The provided URL could not be reached by Linkup.\n" + f"Original error message: {error_msg}." + ) if code == "FETCH_UNSUPPORTED_CONTENT_TYPE": raise LinkupFetchUnsupportedContentTypeError( "The Linkup API returned an unsupported content type error (400). " diff --git a/src/linkup/_errors.py b/src/linkup/_errors.py index d7e0e26..a0721ae 100644 --- a/src/linkup/_errors.py +++ b/src/linkup/_errors.py @@ -76,6 +76,16 @@ class LinkupFetchResponseTooLargeError(Exception): pass +class LinkupFetchTargetUnreachableError(Exception): + """Fetch target unreachable error, raised when the Linkup API returns a 400 status code. + + It is returned when the Linkup API cannot connect to the requested target URL, such as when + the host is unreachable or the request times out before a response is received. + """ + + pass + + class LinkupFetchUnsupportedContentTypeError(Exception): """Unsupported fetch content type error, raised when the Linkup API returns a 400 status code. diff --git a/tests/unit/client_test.py b/tests/unit/client_test.py index 36f7750..c65d12d 100644 --- a/tests/unit/client_test.py +++ b/tests/unit/client_test.py @@ -1043,6 +1043,19 @@ async def test_async_fetch( """, linkup.FetchResponseTooLargeError, ), + ( + 400, + b""" + { + "error": { + "code": "FETCH_TARGET_UNREACHABLE", + "message": "The target URL could not be reached (connection failed or timed out)", + "details": [] + } + } + """, + linkup.FetchTargetUnreachableError, + ), ( 400, b"""