use std::collections::HashMap;
use std::path::Path;
pub(super) fn load_error_severity_overrides(
path: Option<&Path>,
) -> Result<HashMap<String, String>, String> {
let Some(path) = path else {
return Ok(HashMap::new());
};
let payload = super::read_json_file(path)?;
let mapping = payload.get("code_to_severity").unwrap_or(&payload);
let entries = mapping.as_object().ok_or_else(|| {
format!(
"severity map {} must be a JSON object or include code_to_severity object",
path.display()
)
})?;
let mut overrides = HashMap::new();
for (code, severity_value) in entries {
let raw = severity_value.as_str().ok_or_else(|| {
format!(
"severity map {} has non-string severity for code {}",
path.display(),
code
)
})?;
let normalized = raw.trim().to_ascii_lowercase();
if !is_supported_failure_severity(&normalized) {
return Err(format!(
"severity map {} has invalid severity '{}' for code {} (expected info|warn|critical)",
path.display(),
raw,
code
));
}
overrides.insert(code.to_string(), normalized);
}
Ok(overrides)
}
pub(super) fn summarize_error_group(error: &str) -> String {
if error.contains("missing robotrt config") {
return String::from("missing_config");
}
if error.contains("target schema") && error.contains("is lower than current schema") {
return String::from("schema_downgrade_risk");
}
if error.contains("project dir not found") {
return String::from("project_not_found");
}
if error.contains("unsupported target schema") {
return String::from("unsupported_target_schema");
}
let first_line = error.lines().next().unwrap_or("unknown_error").trim();
if first_line.is_empty() {
String::from("unknown_error")
} else {
first_line.to_string()
}
}
pub(super) fn summarize_error_code(error: &str) -> String {
let group = summarize_error_group(error);
let code = match group.as_str() {
"missing_config" => "E_MISSING_CONFIG",
"schema_downgrade_risk" => "E_SCHEMA_DOWNGRADE_RISK",
"project_not_found" => "E_PROJECT_NOT_FOUND",
"unsupported_target_schema" => "E_UNSUPPORTED_TARGET_SCHEMA",
_ => "E_UNKNOWN",
};
code.to_string()
}
pub(super) fn summarize_error_severity(
error: &str,
severity_overrides: &HashMap<String, String>,
) -> String {
let code = summarize_error_code(error);
summarize_error_code_severity(&code, severity_overrides)
}
fn summarize_error_code_severity(
code: &str,
severity_overrides: &HashMap<String, String>,
) -> String {
if let Some(severity) = severity_overrides.get(code) {
return severity.clone();
}
let severity = match code {
"E_MISSING_CONFIG" => "critical",
"E_PROJECT_NOT_FOUND" => "critical",
"E_SCHEMA_DOWNGRADE_RISK" => "warn",
"E_UNSUPPORTED_TARGET_SCHEMA" => "warn",
_ => "info",
};
severity.to_string()
}
fn is_supported_failure_severity(value: &str) -> bool {
matches!(value, "info" | "warn" | "critical")
}