use thiserror::Error;
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum ConfigError {
#[error("API key cannot be empty. Please provide a valid Shopify API key.")]
EmptyApiKey,
#[error("API secret key cannot be empty. Please provide a valid Shopify API secret key.")]
EmptyApiSecretKey,
#[error("Invalid shop domain '{domain}'. Expected format: 'shop-name' or 'shop-name.myshopify.com'.")]
InvalidShopDomain {
domain: String,
},
#[error("Invalid API version '{version}'. Expected format: 'YYYY-MM' (e.g., '2024-01') or 'unstable'.")]
InvalidApiVersion {
version: String,
},
#[error("Invalid scopes: {reason}")]
InvalidScopes {
reason: String,
},
#[error("Missing required field: '{field}'. This field must be set before building the configuration.")]
MissingRequiredField {
field: &'static str,
},
#[error("Invalid host URL '{url}'. Please provide a valid URL with scheme (e.g., 'https://myapp.example.com').")]
InvalidHostUrl {
url: String,
},
#[error("API version '{version}' is deprecated. Please upgrade to '{latest}' or a newer supported version.")]
DeprecatedApiVersion {
version: String,
latest: String,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty_api_key_error_message() {
let error = ConfigError::EmptyApiKey;
let message = error.to_string();
assert!(message.contains("API key cannot be empty"));
assert!(message.contains("valid Shopify API key"));
}
#[test]
fn test_invalid_shop_domain_error_message() {
let error = ConfigError::InvalidShopDomain {
domain: "bad domain!".to_string(),
};
let message = error.to_string();
assert!(message.contains("bad domain!"));
assert!(message.contains("Expected format"));
}
#[test]
fn test_missing_required_field_error_message() {
let error = ConfigError::MissingRequiredField { field: "api_key" };
let message = error.to_string();
assert!(message.contains("api_key"));
assert!(message.contains("must be set"));
}
#[test]
fn test_error_implements_std_error() {
let error = ConfigError::EmptyApiKey;
let _: &dyn std::error::Error = &error;
}
#[test]
fn test_deprecated_api_version_error_message() {
let error = ConfigError::DeprecatedApiVersion {
version: "2024-01".to_string(),
latest: "2025-10".to_string(),
};
let message = error.to_string();
assert!(message.contains("2024-01"));
assert!(message.contains("deprecated"));
assert!(message.contains("2025-10"));
assert!(message.contains("upgrade"));
}
}