diff --git a/src-tauri/src/alerts.rs b/src-tauri/src/alerts.rs index c7ca5b6..12eadc0 100644 --- a/src-tauri/src/alerts.rs +++ b/src-tauri/src/alerts.rs @@ -54,45 +54,81 @@ pub async fn get_github_security_alerts(app: tauri::AppHandle) -> Result { - if response.status() == 422 { - // 422 Unprocessable Entity usually means Dependabot is not enabled - eprintln!("Dependabot not enabled for {}", repo); + let status = response.status(); + + if status == 422 { + // 422 Unprocessable Entity: Dependabot not enabled on this repo + eprintln!("[{}] Dependabot not enabled (HTTP 422)", repo); repo_alerts.push(RepoAlerts { name: repo, alerts: 0, dependabot_enabled: false, + error: None, + }); + } else if !status.is_success() { + // Any other non-2xx: capture the raw body for a useful error message + let body = response.text().await.unwrap_or_default(); + let msg = format!("HTTP {} — {}", status.as_u16(), body); + eprintln!("[{}] GitHub API error: {}", repo, msg); + repo_alerts.push(RepoAlerts { + name: repo, + alerts: 0, + dependabot_enabled: false, + error: Some(msg), }); } else { - match response.json::>().await { - Ok(alerts) => { - let open_alerts = alerts.iter() - .filter(|a| a.state == "open") - .count(); - total_alerts += open_alerts; - repo_alerts.push(RepoAlerts { - name: repo, - alerts: open_alerts, - dependabot_enabled: true, - }); + // 2xx: try to parse the JSON body + // Read raw bytes first so we can log them if parsing fails + match response.bytes().await { + Ok(bytes) => { + match serde_json::from_slice::>(&bytes) { + Ok(alerts) => { + let open_alerts = alerts.iter() + .filter(|a| a.state == "open") + .count(); + total_alerts += open_alerts; + repo_alerts.push(RepoAlerts { + name: repo, + alerts: open_alerts, + dependabot_enabled: true, + error: None, + }); + } + Err(e) => { + // Log the raw body so we can see what GitHub actually returned + let raw = String::from_utf8_lossy(&bytes); + let msg = format!("JSON parse error: {} — body: {}", e, raw); + eprintln!("[{}] {}", repo, msg); + repo_alerts.push(RepoAlerts { + name: repo, + alerts: 0, + dependabot_enabled: false, + error: Some(format!("JSON parse error: {}", e)), + }); + } + } } Err(e) => { - eprintln!("Failed to parse alerts for {}: {}", repo, e); - // If parsing fails, assume Dependabot is not enabled + let msg = format!("Error reading response body: {}", e); + eprintln!("[{}] {}", repo, msg); repo_alerts.push(RepoAlerts { name: repo, alerts: 0, dependabot_enabled: false, + error: Some(msg), }); } } } } Err(e) => { - eprintln!("Failed to fetch alerts for {}: {}", repo, e); + let msg = format!("Network error: {}", e); + eprintln!("[{}] {}", repo, msg); repo_alerts.push(RepoAlerts { name: repo, alerts: 0, dependabot_enabled: false, + error: Some(msg), }); } } @@ -102,4 +138,4 @@ pub async fn get_github_security_alerts(app: tauri::AppHandle) -> Result, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/app/core/services/tauri/tauri.service.ts b/src/app/core/services/tauri/tauri.service.ts index b60d23a..fd8f699 100644 --- a/src/app/core/services/tauri/tauri.service.ts +++ b/src/app/core/services/tauri/tauri.service.ts @@ -16,6 +16,7 @@ export interface RepoAlerts { name: string; alerts: number; dependabot_enabled: boolean; + error?: string; } export interface AlertsResponse { diff --git a/src/app/shared/components/alerts-list/alerts-list.component.html b/src/app/shared/components/alerts-list/alerts-list.component.html index 8f3070b..7190390 100644 --- a/src/app/shared/components/alerts-list/alerts-list.component.html +++ b/src/app/shared/components/alerts-list/alerts-list.component.html @@ -60,13 +60,15 @@
- - + + + {{ repo.alerts }}
diff --git a/src/app/shared/components/alerts-list/alerts-list.component.scss b/src/app/shared/components/alerts-list/alerts-list.component.scss index d49bd71..c32e0d5 100644 --- a/src/app/shared/components/alerts-list/alerts-list.component.scss +++ b/src/app/shared/components/alerts-list/alerts-list.component.scss @@ -179,6 +179,12 @@ color: colors.$text-secondary; cursor: help; } + + &.error { + background: rgba(colors.$danger-color, 0.1); + color: colors.$danger-color; + cursor: help; + } } }