refactor: replace anyhow with thiserror for typed error handling

main
Yoo1tic 2025-07-28 20:23:27 +08:00
parent 660367d8a3
commit f10c2a8afb
8 changed files with 36 additions and 26 deletions

24
Cargo.lock generated
View File

@ -568,7 +568,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2",
"socket2 0.5.10",
"tokio",
"tower-service",
"tracing",
@ -930,7 +930,7 @@ dependencies = [
"quinn-udp",
"rustc-hash",
"rustls",
"socket2",
"socket2 0.5.10",
"thiserror",
"tokio",
"tracing",
@ -967,7 +967,7 @@ dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2",
"socket2 0.5.10",
"tracing",
"windows-sys 0.59.0",
]
@ -1247,6 +1247,16 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "socket2"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
dependencies = [
"libc",
"windows-sys 0.59.0",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@ -1343,9 +1353,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.46.1"
version = "1.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35"
dependencies = [
"backtrace",
"bytes",
@ -1354,9 +1364,9 @@ dependencies = [
"mio",
"pin-project-lite",
"slab",
"socket2",
"socket2 0.6.0",
"tokio-macros",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]

View File

@ -5,13 +5,13 @@ edition = "2024"
[dependencies]
mimalloc = { version = "*" }
backon = "1"
backon = "1.5"
clap = { version = "4.5", features = ["derive"] }
futures = "0.3"
regex = "1.11"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls","http2"] }
serde_json = "1.0"
tokio = { version = "1.46", features = [
tokio = { version = "1.47", features = [
"macros",
"rt-multi-thread",
"time",
@ -22,4 +22,4 @@ async-stream = "0.3"
figment = { version = "0.10", features = ["env", "toml"] }
serde = { version = "1.0", features = ["derive"] }
toml = "0.9"
thiserror = "2.0.12"
thiserror = "2.0"

View File

@ -1,4 +1,4 @@
use crate::error::ValidationError;
use crate::error::ValidatorError;
use clap::Parser;
use figment::{
Figment,
@ -85,7 +85,7 @@ impl Default for KeyCheckerConfig {
}
}
impl KeyCheckerConfig {
pub fn load_config() -> Result<Self, ValidationError> {
pub fn load_config() -> Result<Self, ValidatorError> {
// Define the path to the configuration file
static CONFIG_PATH: LazyLock<PathBuf> = LazyLock::new(|| "Config.toml".into());

View File

@ -1,7 +1,7 @@
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ValidationError {
pub enum ValidatorError {
#[error("HTTP error: {0}")]
ReqwestError(#[from] reqwest::Error),
@ -30,4 +30,4 @@ pub enum ValidationError {
Validation(String),
}
pub type Result<T> = std::result::Result<T, ValidationError>;
pub type Result<T> = std::result::Result<T, ValidatorError>;

View File

@ -1,4 +1,4 @@
use gemini_keychecker::error::ValidationError;
use gemini_keychecker::error::ValidatorError;
use gemini_keychecker::{BANNER, config::KeyCheckerConfig, service::start_validation};
use mimalloc::MiMalloc;
@ -8,7 +8,7 @@ static GLOBAL: MiMalloc = MiMalloc;
/// Main function - displays banner and starts validation service
#[tokio::main]
async fn main() -> Result<(), ValidationError> {
async fn main() -> Result<(), ValidatorError> {
// Display banner and configuration status at startup
println!("{BANNER}");

View File

@ -1,8 +1,8 @@
use crate::{config::KeyCheckerConfig, error::ValidationError};
use crate::{config::KeyCheckerConfig, error::ValidatorError};
use reqwest::Client;
use std::time::Duration;
pub fn client_builder(config: &KeyCheckerConfig) -> Result<Client, ValidationError> {
pub fn client_builder(config: &KeyCheckerConfig) -> Result<Client, ValidatorError> {
// Set the maximum number of connections per host based on concurrency.
let pool_size = config.concurrency / 2;

View File

@ -4,14 +4,14 @@ use tokio::time::Duration;
use url::Url;
use crate::config::TEST_MESSAGE_BODY;
use crate::error::ValidationError;
use crate::error::ValidatorError;
use crate::types::GeminiKey;
pub async fn validate_key(
client: Client,
api_endpoint: impl IntoUrl,
api_key: GeminiKey,
) -> Result<GeminiKey, ValidationError> {
) -> Result<GeminiKey, ValidatorError> {
let api_endpoint = api_endpoint.into_url()?;
match send_test_request(client, &api_endpoint, api_key.clone()).await {
@ -21,13 +21,13 @@ pub async fn validate_key(
StatusCode::OK => Ok(api_key),
StatusCode::UNAUTHORIZED
| StatusCode::FORBIDDEN
| StatusCode::TOO_MANY_REQUESTS => Err(ValidationError::KeyInvalid),
_ => Err(ValidationError::ReqwestError(
| StatusCode::TOO_MANY_REQUESTS => Err(ValidatorError::KeyInvalid),
_ => Err(ValidatorError::ReqwestError(
response.error_for_status().unwrap_err(),
)),
}
}
Err(e) => Err(ValidationError::ReqwestError(e)),
Err(e) => Err(ValidatorError::ReqwestError(e)),
}
}

View File

@ -1,4 +1,4 @@
use crate::error::ValidationError;
use crate::error::ValidatorError;
use async_stream::stream;
use futures::{pin_mut, stream::StreamExt};
use reqwest::Client;
@ -26,7 +26,7 @@ impl ValidationService {
}
}
pub async fn validate_keys(&self, keys: Vec<GeminiKey>) -> Result<(), ValidationError> {
pub async fn validate_keys(&self, keys: Vec<GeminiKey>) -> Result<(), ValidatorError> {
let start_time = Instant::now();
// Create channel for streaming keys from producer to consumer
@ -74,7 +74,7 @@ impl ValidationService {
}
/// 启动验证服务 - 封装了所有启动逻辑
pub async fn start_validation() -> Result<(), ValidationError> {
pub async fn start_validation() -> Result<(), ValidatorError> {
let config = KeyCheckerConfig::load_config()?;
// 加载密钥