From b950a3b4c592b00d4dc4fc349f5e4835fc2760d2 Mon Sep 17 00:00:00 2001 From: Mateusz Sterczewski Date: Wed, 25 Mar 2026 08:34:33 +0100 Subject: [PATCH] CM-61550: Handle HTTP 408 with a user-friendly slow connection message Adds HttpRequestTimeoutError as a distinct subclass of RequestHttpError for 408 responses, so users see a specific message about slow connections instead of the generic "unable to complete scan" error. Co-Authored-By: Claude Sonnet 4.6 --- cycode/cli/exceptions/custom_exceptions.py | 14 ++++++++++++++ cycode/cyclient/cycode_client_base.py | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/cycode/cli/exceptions/custom_exceptions.py b/cycode/cli/exceptions/custom_exceptions.py index 78781914..24cf18d6 100644 --- a/cycode/cli/exceptions/custom_exceptions.py +++ b/cycode/cli/exceptions/custom_exceptions.py @@ -55,6 +55,14 @@ def __str__(self) -> str: return f'HTTP unauthorized error occurred during the request. Message: {self.error_message}' +class HttpRequestTimeoutError(RequestHttpError): + def __init__(self, error_message: str, response: Response) -> None: + super().__init__(408, error_message, response) + + def __str__(self) -> str: + return f'HTTP request timeout error occurred during the request. Message: {self.error_message}' + + class ZipTooLargeError(CycodeError): def __init__(self, size_limit: int) -> None: self.size_limit = size_limit @@ -93,6 +101,12 @@ def __str__(self) -> str: code='timeout_error', message='The request timed out. Please try again by executing the `cycode scan` command', ), + HttpRequestTimeoutError: CliError( + soft_fail=True, + code='request_timeout_error', + message='The scan upload timed out. This may be due to a slow connection. ' + 'Please try again by executing the `cycode scan` command', + ), HttpUnauthorizedError: CliError( soft_fail=True, code='auth_error', diff --git a/cycode/cyclient/cycode_client_base.py b/cycode/cyclient/cycode_client_base.py index 4b2e2698..b1bc7669 100644 --- a/cycode/cyclient/cycode_client_base.py +++ b/cycode/cyclient/cycode_client_base.py @@ -9,6 +9,7 @@ from tenacity import retry, retry_if_exception, stop_after_attempt, wait_random_exponential from cycode.cli.exceptions.custom_exceptions import ( + HttpRequestTimeoutError, HttpUnauthorizedError, RequestConnectionError, RequestError, @@ -185,4 +186,7 @@ def _get_http_exception(e: exceptions.HTTPError) -> RequestError: if e.response.status_code == 401: return HttpUnauthorizedError(e.response.text, e.response) + if e.response.status_code == 408: + return HttpRequestTimeoutError(e.response.text, e.response) + return RequestHttpError(e.response.status_code, e.response.text, e.response)