Skip to content
Open
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## 2.6.2

### Fixed: SBOM fetch failures no longer produce empty reports

- `Core.get_sbom_data` now raises `APIFailure` when the full-scan stream fetch
fails, so the run exits through the CLI's API-error handling (exit code 3 by
default; `--disable-blocking` still exits 0) instead of writing empty
GitLab dependency-scanning, license, and SARIF reports.
- The underlying stream-parse failure was fixed in `socketdev` 3.4.2 (already
pinned at `3.5.0`): unrecognized purl types such as `generic` now resolve
instead of raising, and individual unparseable artifacts are skipped rather
than failing the whole response.

## 2.6.0

### Changed: pin all Python dependencies
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "hatchling.build"

[project]
name = "socketsecurity"
version = "2.6.0"
version = "2.6.2"
requires-python = ">= 3.11"
license = {"file" = "LICENSE"}
dependencies = [
Expand Down
2 changes: 1 addition & 1 deletion socketsecurity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__author__ = 'socket.dev'
__version__ = '2.6.0'
__version__ = '2.6.2'
USER_AGENT = f'SocketPythonCLI/{__version__}'
10 changes: 7 additions & 3 deletions socketsecurity/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,13 @@ def get_sbom_data(self, full_scan_id: str) -> Dict[str, SocketArtifact]:
"""Returns SBOM artifacts for a full scan keyed by artifact ID."""
response = self.sdk.fullscans.stream(self.config.org_slug, full_scan_id, use_types=True)
if not response.success:
log.debug(f"Failed to get SBOM data for full-scan {full_scan_id}")
log.debug(response.message)
return {}
# Raise instead of returning {} so a failed fetch surfaces as an
# API error (exit code 3 by default) rather than empty reports.
log.error(f"Failed to get SBOM data for full-scan {full_scan_id}")
log.error(response.message)
raise APIFailure(
f"Failed to get SBOM data for full-scan {full_scan_id}: {response.message}"
)
if not hasattr(response, "artifacts") or not response.artifacts:
return {}
return response.artifacts
Expand Down
20 changes: 19 additions & 1 deletion tests/core/test_sdk_methods.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
from socketdev.fullscans import FullScanParams
from socketdev.exceptions import APIFailure
from socketdev.fullscans import FullScanParams, FullScanStreamResponse

from socketsecurity.config import CliConfig
from socketsecurity.core import Core
Expand Down Expand Up @@ -263,6 +264,23 @@ def test_get_added_and_removed_packages_license_override(core):
include_license_details="true",
)

def test_get_sbom_data_failure_raises(core):
"""A failed SBOM stream fetch raises instead of returning {}.

Returning {} let report generation continue and emit empty results with
exit code 0; raising routes the failure through the CLI's API-error
handling instead.
"""
core.sdk.fullscans.stream.side_effect = None
core.sdk.fullscans.stream.return_value = FullScanStreamResponse.from_dict({
"success": False,
"status": 200,
"message": "Error parsing stream response",
})

with pytest.raises(APIFailure, match="Failed to get SBOM data"):
core.get_sbom_data("head")

def test_empty_alerts_preserved(core):
"""Test that empty alerts arrays stay as empty arrays and don't become None"""
# Get the scan that contains dp2 (which has empty alerts array)
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.