use crate::clients::HttpError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum RestError {
#[error("The Admin REST API has been deprecated. Please use the GraphQL Admin API. For more information see https://www.shopify.com/ca/partners/blog/all-in-on-graphql")]
RestApiDisabled,
#[error("Invalid REST API path: {path}")]
InvalidPath {
path: String,
},
#[error(transparent)]
Http(#[from] HttpError),
}
#[cfg(test)]
mod tests {
use super::*;
use crate::clients::{HttpResponseError, MaxHttpRetriesExceededError};
#[test]
fn test_rest_api_disabled_error_message_matches_ruby_sdk() {
let error = RestError::RestApiDisabled;
let message = error.to_string();
assert!(message.contains("The Admin REST API has been deprecated"));
assert!(message.contains("Please use the GraphQL Admin API"));
assert!(message.contains("https://www.shopify.com/ca/partners/blog/all-in-on-graphql"));
}
#[test]
fn test_invalid_path_error_includes_path_in_message() {
let error = RestError::InvalidPath {
path: "/invalid/path".to_string(),
};
let message = error.to_string();
assert!(message.contains("Invalid REST API path"));
assert!(message.contains("/invalid/path"));
}
#[test]
fn test_invalid_path_error_with_empty_path() {
let error = RestError::InvalidPath {
path: String::new(),
};
let message = error.to_string();
assert!(message.contains("Invalid REST API path"));
assert_eq!(message, "Invalid REST API path: ");
}
#[test]
fn test_http_error_wraps_http_response_error() {
let http_error = HttpError::Response(HttpResponseError {
code: 404,
message: r#"{"error":"Not Found"}"#.to_string(),
error_reference: Some("abc-123".to_string()),
});
let rest_error = RestError::Http(http_error);
let message = rest_error.to_string();
assert!(message.contains("Not Found"));
}
#[test]
fn test_from_http_error_conversion() {
let http_error = HttpError::Response(HttpResponseError {
code: 500,
message: r#"{"error":"Internal Server Error"}"#.to_string(),
error_reference: None,
});
let rest_error: RestError = http_error.into();
assert!(matches!(rest_error, RestError::Http(_)));
}
#[test]
fn test_all_error_variants_implement_std_error() {
let disabled_error: &dyn std::error::Error = &RestError::RestApiDisabled;
let _ = disabled_error;
let path_error: &dyn std::error::Error = &RestError::InvalidPath {
path: "test".to_string(),
};
let _ = path_error;
let http_error: &dyn std::error::Error =
&RestError::Http(HttpError::Response(HttpResponseError {
code: 400,
message: "test".to_string(),
error_reference: None,
}));
let _ = http_error;
}
#[test]
fn test_http_error_wraps_max_retries_exceeded() {
let http_error = HttpError::MaxRetries(MaxHttpRetriesExceededError {
code: 429,
tries: 3,
message: r#"{"error":"Rate limited"}"#.to_string(),
error_reference: None,
});
let rest_error = RestError::Http(http_error);
let message = rest_error.to_string();
assert!(message.contains("Exceeded maximum retry count"));
assert!(message.contains("3"));
}
}