Skip to content

Commit f995885

Browse files
CM-65436: retry scan notification on 404 after presigned upload
After a successful S3 presigned POST, the scan service calls the file service to verify the upload exists. A transient 403 from the file service's S3 client is silently mapped to NotFound, causing the scan service to return 404. Add a targeted retry (up to 3 attempts, random exponential backoff) exclusively on the notify-server call so the scan proceeds without requiring a full re-upload. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d53991b commit f995885

1 file changed

Lines changed: 25 additions & 3 deletions

File tree

cycode/cli/apps/scan/code_scanner.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import requests
77
import typer
8+
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_random_exponential
89

910
from cycode.cli import consts
1011
from cycode.cli.apps.scan.aggregation_report import try_set_aggregation_report_url_if_needed
@@ -22,6 +23,7 @@
2223
from cycode.cli.files_collector.path_documents import get_relevant_documents
2324
from cycode.cli.files_collector.sca.sca_file_collector import add_sca_dependencies_tree_documents_if_needed
2425
from cycode.cli.files_collector.zip_documents import zip_documents
26+
from cycode.cli.exceptions.custom_exceptions import RequestHttpError
2527
from cycode.cli.models import CliError, Document, LocalScanResult
2628
from cycode.cli.utils.path_utils import get_absolute_path, get_path_by_os
2729
from cycode.cli.utils.progress_bar import ScanProgressBarSection
@@ -32,7 +34,7 @@
3234
set_issue_detected_by_scan_results,
3335
should_use_presigned_upload,
3436
)
35-
from cycode.cyclient.models import ZippedFileScanResult
37+
from cycode.cyclient.models import ScanInitializationResponse, ZippedFileScanResult
3638
from cycode.logger import get_logger
3739

3840
if TYPE_CHECKING:
@@ -295,6 +297,26 @@ def scan_documents(
295297
print_local_scan_results(ctx, local_scan_results, errors)
296298

297299

300+
@retry(
301+
retry=retry_if_exception(lambda e: isinstance(e, RequestHttpError) and e.status_code == 404),
302+
stop=stop_after_attempt(3),
303+
wait=wait_random_exponential(multiplier=1, min=1, max=5),
304+
reraise=True,
305+
)
306+
def _notify_scan_from_upload_id(
307+
cycode_client: 'ScanClient',
308+
scan_type: str,
309+
upload_id: str,
310+
zipped_documents: 'InMemoryZip',
311+
scan_parameters: dict,
312+
is_git_diff: bool,
313+
is_commit_range: bool,
314+
) -> 'ScanInitializationResponse':
315+
return cycode_client.scan_repository_from_upload_id(
316+
scan_type, upload_id, zipped_documents, scan_parameters, is_git_diff, is_commit_range
317+
)
318+
319+
298320
def _perform_scan_v4_async(
299321
cycode_client: 'ScanClient',
300322
zipped_documents: 'InMemoryZip',
@@ -312,8 +334,8 @@ def _perform_scan_v4_async(
312334
)
313335
logger.debug('Uploaded zip to presigned URL')
314336

315-
scan_async_result = cycode_client.scan_repository_from_upload_id(
316-
scan_type, upload_link.upload_id, zipped_documents, scan_parameters, is_git_diff, is_commit_range
337+
scan_async_result = _notify_scan_from_upload_id(
338+
cycode_client, scan_type, upload_link.upload_id, zipped_documents, scan_parameters, is_git_diff, is_commit_range
317339
)
318340
logger.debug(
319341
'Presigned upload scan request triggered, %s',

0 commit comments

Comments
 (0)