Skip to content

Commit 77b18a7

Browse files
leliaclaude
andcommitted
fix(core): raise on SBOM fetch failure instead of writing empty reports (CE-362)
get_sbom_data returned {} when the full-scan stream fetch failed, so report generation continued and produced empty GitLab dependency scanning, license, and SARIF output with exit code 0. Raise APIFailure instead so the failure goes through the CLI's existing API-error handling (exit code 3 by default, still exit 0 with --disable-blocking). Bump the socketdev floor to 3.4.2, the bundled release that adds the missing purl types (e.g. "generic") and per-artifact parse resilience that caused this failure mode. Merge after socketdev 3.4.2 is on PyPI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent ebdc3e4 commit 77b18a7

3 files changed

Lines changed: 27 additions & 5 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ dependencies = [
1616
'GitPython',
1717
'packaging',
1818
'python-dotenv',
19-
"socketdev>=3.3.0,<4.0.0",
19+
"socketdev>=3.4.2,<4.0.0",
2020
"bs4>=0.0.2",
2121
"markdown>=3.10",
2222
"brotli>=1.0.9; platform_python_implementation == 'CPython'",

socketsecurity/core/__init__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,13 @@ def get_sbom_data(self, full_scan_id: str) -> Dict[str, SocketArtifact]:
154154
"""Returns SBOM artifacts for a full scan keyed by artifact ID."""
155155
response = self.sdk.fullscans.stream(self.config.org_slug, full_scan_id, use_types=True)
156156
if not response.success:
157-
log.debug(f"Failed to get SBOM data for full-scan {full_scan_id}")
158-
log.debug(response.message)
159-
return {}
157+
# Raise instead of returning {} so a failed fetch surfaces as an
158+
# API error (exit code 3 by default) rather than empty reports.
159+
log.error(f"Failed to get SBOM data for full-scan {full_scan_id}")
160+
log.error(response.message)
161+
raise APIFailure(
162+
f"Failed to get SBOM data for full-scan {full_scan_id}: {response.message}"
163+
)
160164
if not hasattr(response, "artifacts") or not response.artifacts:
161165
return {}
162166
return response.artifacts

tests/core/test_sdk_methods.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
2-
from socketdev.fullscans import FullScanParams
2+
from socketdev.exceptions import APIFailure
3+
from socketdev.fullscans import FullScanParams, FullScanStreamResponse
34

45
from socketsecurity.config import CliConfig
56
from socketsecurity.core import Core
@@ -263,6 +264,23 @@ def test_get_added_and_removed_packages_license_override(core):
263264
include_license_details="true",
264265
)
265266

267+
def test_get_sbom_data_failure_raises(core):
268+
"""A failed SBOM stream fetch raises instead of returning {} (CE-362).
269+
270+
Returning {} let report generation continue and emit empty results with
271+
exit code 0; raising routes the failure through the CLI's API-error
272+
handling instead.
273+
"""
274+
core.sdk.fullscans.stream.side_effect = None
275+
core.sdk.fullscans.stream.return_value = FullScanStreamResponse.from_dict({
276+
"success": False,
277+
"status": 200,
278+
"message": "Error parsing stream response",
279+
})
280+
281+
with pytest.raises(APIFailure, match="Failed to get SBOM data"):
282+
core.get_sbom_data("head")
283+
266284
def test_empty_alerts_preserved(core):
267285
"""Test that empty alerts arrays stay as empty arrays and don't become None"""
268286
# Get the scan that contains dp2 (which has empty alerts array)

0 commit comments

Comments
 (0)