use serde::Deserialize;
use std::collections::HashMap;
use std::fmt;
#[derive(Debug, Clone, Deserialize)]
pub struct CpqErrorResponse {
pub message: String,
#[serde(rename = "errorCode", default)]
pub error_code: Option<String>,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
impl fmt::Display for CpqErrorResponse {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(code) = &self.error_code {
write!(f, "[{code}] {}", self.message)
} else {
write!(f, "{}", self.message)
}
}
}
impl std::error::Error for CpqErrorResponse {}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_support::Must;
#[test]
fn test_cpq_error_deserialize_with_code() {
let json = serde_json::json!({
"message": "Quote not found",
"errorCode": "ENTITY_NOT_FOUND"
});
let err: CpqErrorResponse = serde_json::from_value(json).must();
assert_eq!(err.message, "Quote not found");
assert_eq!(err.error_code.as_deref(), Some("ENTITY_NOT_FOUND"));
}
#[test]
fn test_cpq_error_deserialize_without_code() {
let json = serde_json::json!({
"message": "Internal error occurred"
});
let err: CpqErrorResponse = serde_json::from_value(json).must();
assert_eq!(err.message, "Internal error occurred");
assert!(err.error_code.is_none());
}
#[test]
fn test_cpq_error_captures_extra_fields() {
let json = serde_json::json!({
"message": "Validation failed",
"errorCode": "VALIDATION_ERROR",
"fields": ["SBQQ__Quantity__c"],
"statusCode": 400
});
let err: CpqErrorResponse = serde_json::from_value(json).must();
assert!(err.extra.contains_key("fields"));
assert!(err.extra.contains_key("statusCode"));
}
#[test]
fn test_cpq_error_display_with_code() {
let err = CpqErrorResponse {
message: "Not found".to_string(),
error_code: Some("NOT_FOUND".to_string()),
extra: HashMap::new(),
};
assert_eq!(err.to_string(), "[NOT_FOUND] Not found");
}
#[test]
fn test_cpq_error_display_without_code() {
let err = CpqErrorResponse {
message: "Something went wrong".to_string(),
error_code: None,
extra: HashMap::new(),
};
assert_eq!(err.to_string(), "Something went wrong");
}
}