use thiserror::Error;
#[derive(Error, Debug)]
pub enum CliError {
#[error("Database error: {0}")]
Database(#[from] alopex_embedded::Error),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Invalid argument: {0}")]
InvalidArgument(String),
#[error("プロファイル '{0}' が見つかりません。alopex profile list で一覧を確認してください。")]
#[allow(dead_code)]
ProfileNotFound(String),
#[error(
"`--profile` と `--data-dir` は同時に指定できません。どちらか一方を使用してください。"
)]
#[allow(dead_code)]
ConflictingOptions,
#[error(
"トランザクション ID '{0}' は無効です。alopex kv txn begin で新しいトランザクションを開始してください。"
)]
#[allow(dead_code)]
InvalidTransactionId(String),
#[error(
"トランザクション '{0}' がタイムアウトしました(60秒)。自動的にロールバックされました。"
)]
#[allow(dead_code)]
TransactionTimeout(String),
#[error("Query timeout: {0}. Suggestion: Use --deadline 120s to increase timeout.")]
#[allow(dead_code)]
Timeout(String),
#[error("Query cancelled by user.")]
#[allow(dead_code)]
Cancelled,
#[error("SQL クエリを指定してください。引数、-f オプション、または標準入力から入力できます。")]
#[allow(dead_code)]
NoQueryProvided,
#[error("未知のインデックスタイプ: '{0}'。許可値: minmax, bloom")]
#[allow(dead_code)]
UnknownIndexType(String),
#[error("未知の圧縮形式: '{0}'。許可値: lz4, zstd, none")]
#[allow(dead_code)]
UnknownCompressionType(String),
#[error("ファイルフォーマット v{file} は CLI v{cli} でサポートされていません。CLI をアップグレードしてください。")]
#[allow(dead_code)]
IncompatibleVersion { cli: String, file: String },
#[error("S3 error: {0}")]
#[allow(dead_code)]
S3(String),
#[error("Credentials error: {0}")]
Credentials(String),
#[error("Parse error: {0}")]
#[allow(dead_code)]
Parse(String),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Server connection error: {0}")]
#[allow(dead_code)]
ServerConnection(String),
#[error("Server does not support this command: {0}")]
#[allow(dead_code)]
ServerUnsupported(String),
}
pub type Result<T> = std::result::Result<T, CliError>;
pub fn handle_error(error: CliError, verbose: bool) {
if verbose {
eprintln!("Error: {:?}", error); } else {
eprintln!("Error: {}", error); }
std::process::exit(1);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_invalid_argument_error() {
let err = CliError::InvalidArgument("test message".to_string());
assert_eq!(format!("{}", err), "Invalid argument: test message");
}
#[test]
fn test_s3_error() {
let err = CliError::S3("bucket not found".to_string());
assert_eq!(format!("{}", err), "S3 error: bucket not found");
}
#[test]
fn test_credentials_error() {
let err = CliError::Credentials("AWS_ACCESS_KEY_ID not set".to_string());
assert_eq!(
format!("{}", err),
"Credentials error: AWS_ACCESS_KEY_ID not set"
);
}
#[test]
fn test_parse_error() {
let err = CliError::Parse("invalid JSON".to_string());
assert_eq!(format!("{}", err), "Parse error: invalid JSON");
}
#[test]
fn test_io_error_from() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let err: CliError = io_err.into();
assert!(matches!(err, CliError::Io(_)));
}
}