use mkt_core::error::MktError;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct GoogleApiErrorResponse {
pub error: GoogleApiError,
}
#[derive(Debug, Deserialize)]
pub struct GoogleApiError {
#[serde(default)]
pub code: u16,
#[serde(default)]
pub message: String,
#[serde(default)]
pub status: String,
}
impl GoogleApiErrorResponse {
pub fn into_mkt_error(self, http_status: u16) -> MktError {
let status = if http_status == 0 {
self.error.code
} else {
http_status
};
let message = if self.error.status.is_empty() {
self.error.message
} else {
format!("{} — {}", self.error.status, self.error.message)
};
MktError::ApiError {
provider: "google".into(),
status,
message,
retry_after: None,
}
}
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn deserialize_google_api_error() {
let body = serde_json::json!({
"error": {
"code": 401,
"message": "Request had invalid authentication credentials.",
"status": "UNAUTHENTICATED"
}
});
let parsed: GoogleApiErrorResponse =
serde_json::from_value(body).expect("should deserialize");
assert_eq!(parsed.error.code, 401);
assert_eq!(parsed.error.status, "UNAUTHENTICATED");
}
#[test]
fn into_mkt_error_preserves_status_and_message() {
let resp = GoogleApiErrorResponse {
error: GoogleApiError {
code: 401,
message: "bad token".into(),
status: "UNAUTHENTICATED".into(),
},
};
let err = resp.into_mkt_error(401);
let msg = err.to_string();
assert!(msg.contains("google"));
assert!(msg.contains("401"));
assert!(msg.contains("UNAUTHENTICATED"));
}
}