Skip to content

Commit 65ef71f

Browse files
committed
Fail report-only JSON when detail queries fail
A report-only `scan --json` (`--prune` with no mode) with a severity floor or `enabled: false` fetches patch details to fill `policy.filtered[]`. If every query failed it still printed a success envelope and exited 0. It now reports the error and exits 1, like the agent and vendored runs. Human-mode policy warnings now print `Warning: <detail>` like the rest of `scan`; the code stays in the JSON `warnings[]` entry. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BKsyzefGhAnPkYmXCwq3H3
1 parent f680990 commit 65ef71f

3 files changed

Lines changed: 31 additions & 3 deletions

File tree

‎crates/socket-patch-cli/src/commands/scan/mod.rs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,7 +2057,7 @@ async fn run_scan(
20572057
// `enabled: false` still hides candidates; report them like the
20582058
// human arm does (the detail fetch runs only then).
20592059
if !apply && !vendor && policy.reports_selection() && !all_packages_with_patches.is_empty() {
2060-
let _ = discover_selected(
2060+
if let Err((code, message)) = discover_selected(
20612061
&api_client,
20622062
&all_packages_with_patches,
20632063
can_access_paid_patches,
@@ -2067,7 +2067,11 @@ async fn run_scan(
20672067
telemetry,
20682068
Some(&mut result),
20692069
)
2070-
.await;
2070+
.await
2071+
{
2072+
emit_discovery_error_json(&mut result, &message);
2073+
return code;
2074+
}
20712075
}
20722076

20732077
// --- Apply path (if requested) -----------------------------------

‎crates/socket-patch-cli/src/commands/scan/policy.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ impl ScanPolicy {
480480
return;
481481
}
482482
for w in &self.warnings {
483-
eprintln!("Warning ({}): {}", w.code, w.detail);
483+
eprintln!("Warning: {}", w.detail);
484484
}
485485
}
486486

‎crates/socket-patch-cli/tests/e2e_socket_yml_policy.rs‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,30 @@ async fn enabled_false_reports_and_writes_nothing() {
684684
assert_eq!(doc["redirect"]["redirected"], 0);
685685
}
686686

687+
#[tokio::test]
688+
#[serial]
689+
async fn report_only_json_fails_when_every_detail_query_fails() {
690+
let server = MockServer::start().await;
691+
Mock::given(method("GET"))
692+
.and(path_regex(format!("^/v0/orgs/{ORG}/patches/by-package/.+$")))
693+
.respond_with(ResponseTemplate::new(500))
694+
.with_priority(1)
695+
.mount(&server)
696+
.await;
697+
mount_api(&server, catalog()).await;
698+
// `--prune` with no mode is the report-only arm.
699+
let repo = Repo::new(Some("version: 2\npatches:\n minSeverity: critical\n"));
700+
let before = repo.snapshot();
701+
let (code, doc) = scan_json(&repo.dir("services/web"), &server.uri(), &["--prune"], &[]);
702+
assert_eq!(code, 1, "{doc:#}");
703+
assert_eq!(doc["status"], "error", "{doc:#}");
704+
assert!(
705+
doc["error"].as_str().unwrap_or_default().contains("patch-detail queries failed"),
706+
"{doc:#}"
707+
);
708+
assert_eq!(repo.snapshot(), before);
709+
}
710+
687711
#[tokio::test]
688712
#[serial]
689713
async fn recorded_merged_patch_below_a_new_floor_is_kept() {

0 commit comments

Comments
 (0)