提交qiming-mcp-proxy
This commit is contained in:
344
qiming-mcp-proxy/voice-cli/src/error.rs
Normal file
344
qiming-mcp-proxy/voice-cli/src/error.rs
Normal file
@@ -0,0 +1,344 @@
|
||||
use axum::Json;
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use config::ConfigError;
|
||||
use serde_json::json;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum VoiceCliError {
|
||||
#[error("{0}")]
|
||||
Config(String),
|
||||
|
||||
#[error("{0}")]
|
||||
AudioProcessing(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Transcription(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Model(String),
|
||||
|
||||
#[error("{0}")]
|
||||
FileIo(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Http(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Serialization(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Json(String),
|
||||
|
||||
#[error("{0}")]
|
||||
ConfigRs(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Daemon(String),
|
||||
|
||||
#[error("{0}")]
|
||||
UnsupportedFormat(String),
|
||||
|
||||
#[error("{0}")]
|
||||
FileTooLarge(String),
|
||||
|
||||
#[error("{0}")]
|
||||
ModelNotFound(String),
|
||||
|
||||
#[error("{0}")]
|
||||
InvalidModelName(String),
|
||||
|
||||
// Worker pool related errors
|
||||
#[error("{0}")]
|
||||
WorkerPoolError(String),
|
||||
|
||||
#[error("{0}")]
|
||||
TranscriptionTimeout(String),
|
||||
|
||||
#[error("{0}")]
|
||||
TranscriptionFailed(String),
|
||||
|
||||
// Audio processing specific errors
|
||||
#[error("{0}")]
|
||||
AudioConversionFailed(String),
|
||||
|
||||
#[error("{0}")]
|
||||
AudioProbeError(String),
|
||||
|
||||
#[error("{0}")]
|
||||
TempFileError(String),
|
||||
|
||||
// Multipart form handling errors
|
||||
#[error("{0}")]
|
||||
MultipartError(String),
|
||||
|
||||
#[error("{0}")]
|
||||
MissingField(String),
|
||||
|
||||
// Network related errors
|
||||
#[error("{0}")]
|
||||
Network(String),
|
||||
|
||||
// Storage related errors
|
||||
#[error("{0}")]
|
||||
Storage(String),
|
||||
|
||||
// Task management errors
|
||||
#[error("{0}")]
|
||||
TaskManagementDisabled(String),
|
||||
|
||||
#[error("{0}")]
|
||||
NotFound(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Initialization(String),
|
||||
|
||||
// TTS related errors
|
||||
#[error("{0}")]
|
||||
TtsError(String),
|
||||
|
||||
#[error("{0}")]
|
||||
InvalidInput(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Io(String),
|
||||
}
|
||||
|
||||
impl VoiceCliError {
|
||||
// ===========================================
|
||||
// 工厂方法 - 创建带国际化消息的错误
|
||||
// ===========================================
|
||||
|
||||
pub fn config_error(detail: impl Into<String>) -> Self {
|
||||
Self::Config(t!("errors.voice.config", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn audio_processing_error(detail: impl Into<String>) -> Self {
|
||||
Self::AudioProcessing(
|
||||
t!("errors.voice.audio_processing", detail = detail.into()).to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn transcription_error(detail: impl Into<String>) -> Self {
|
||||
Self::Transcription(t!("errors.voice.transcription", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn model_error(detail: impl Into<String>) -> Self {
|
||||
Self::Model(t!("errors.voice.model", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn file_io_error(detail: impl Into<String>) -> Self {
|
||||
Self::FileIo(t!("errors.voice.file_io", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn http_error(detail: impl Into<String>) -> Self {
|
||||
Self::Http(t!("errors.voice.http", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn serialization_error(detail: impl Into<String>) -> Self {
|
||||
Self::Serialization(t!("errors.voice.serialization", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn json_error(detail: impl Into<String>) -> Self {
|
||||
Self::Json(t!("errors.voice.json", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn config_rs_error(detail: impl Into<String>) -> Self {
|
||||
Self::ConfigRs(t!("errors.voice.config_rs", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn daemon_error(detail: impl Into<String>) -> Self {
|
||||
Self::Daemon(t!("errors.voice.daemon", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn unsupported_format(detail: impl Into<String>) -> Self {
|
||||
Self::UnsupportedFormat(
|
||||
t!("errors.voice.unsupported_format", detail = detail.into()).to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn file_too_large(size: usize, max: usize) -> Self {
|
||||
Self::FileTooLarge(t!("errors.voice.file_too_large", size = size, max = max).to_string())
|
||||
}
|
||||
|
||||
pub fn model_not_found(model: impl Into<String>) -> Self {
|
||||
Self::ModelNotFound(t!("errors.voice.model_not_found", model = model.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn invalid_model_name(model: impl Into<String>) -> Self {
|
||||
Self::InvalidModelName(
|
||||
t!("errors.voice.invalid_model_name", model = model.into()).to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn worker_pool_error(detail: impl Into<String>) -> Self {
|
||||
Self::WorkerPoolError(t!("errors.voice.worker_pool", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn transcription_timeout(seconds: u64) -> Self {
|
||||
Self::TranscriptionTimeout(
|
||||
t!("errors.voice.transcription_timeout", seconds = seconds).to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn transcription_failed(detail: impl Into<String>) -> Self {
|
||||
Self::TranscriptionFailed(
|
||||
t!("errors.voice.transcription_failed", detail = detail.into()).to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn audio_conversion_failed(detail: impl Into<String>) -> Self {
|
||||
Self::AudioConversionFailed(
|
||||
t!(
|
||||
"errors.voice.audio_conversion_failed",
|
||||
detail = detail.into()
|
||||
)
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn audio_probe_error(detail: impl Into<String>) -> Self {
|
||||
Self::AudioProbeError(
|
||||
t!("errors.voice.audio_probe_error", detail = detail.into()).to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn temp_file_error(detail: impl Into<String>) -> Self {
|
||||
Self::TempFileError(t!("errors.voice.temp_file_error", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn multipart_error(detail: impl Into<String>) -> Self {
|
||||
Self::MultipartError(t!("errors.voice.multipart_error", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn missing_field(field: impl Into<String>) -> Self {
|
||||
Self::MissingField(t!("errors.voice.missing_field", field = field.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn network_error(detail: impl Into<String>) -> Self {
|
||||
Self::Network(t!("errors.voice.network", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn storage_error(detail: impl Into<String>) -> Self {
|
||||
Self::Storage(t!("errors.voice.storage", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn task_management_disabled() -> Self {
|
||||
Self::TaskManagementDisabled(t!("errors.voice.task_management_disabled").to_string())
|
||||
}
|
||||
|
||||
pub fn not_found(resource: impl Into<String>) -> Self {
|
||||
Self::NotFound(t!("errors.voice.not_found", resource = resource.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn initialization_error(detail: impl Into<String>) -> Self {
|
||||
Self::Initialization(t!("errors.voice.initialization", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn tts_error(detail: impl Into<String>) -> Self {
|
||||
Self::TtsError(t!("errors.voice.tts", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn invalid_input(detail: impl Into<String>) -> Self {
|
||||
Self::InvalidInput(t!("errors.voice.invalid_input", detail = detail.into()).to_string())
|
||||
}
|
||||
|
||||
pub fn io_error(detail: impl Into<String>) -> Self {
|
||||
Self::Io(t!("errors.voice.io", detail = detail.into()).to_string())
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================
|
||||
// 从外部错误类型转换
|
||||
// ===========================================
|
||||
|
||||
impl From<std::io::Error> for VoiceCliError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
Self::file_io_error(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reqwest::Error> for VoiceCliError {
|
||||
fn from(err: reqwest::Error) -> Self {
|
||||
Self::http_error(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_yaml::Error> for VoiceCliError {
|
||||
fn from(err: serde_yaml::Error) -> Self {
|
||||
Self::serialization_error(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for VoiceCliError {
|
||||
fn from(err: serde_json::Error) -> Self {
|
||||
Self::json_error(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ConfigError> for VoiceCliError {
|
||||
fn from(err: ConfigError) -> Self {
|
||||
Self::config_rs_error(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for VoiceCliError {
|
||||
fn into_response(self) -> Response {
|
||||
let (status, error_message) = match self {
|
||||
VoiceCliError::Config(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::AudioProcessing(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::Transcription(_) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, self.to_string())
|
||||
}
|
||||
VoiceCliError::Model(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::FileIo(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::Http(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::Serialization(_) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, self.to_string())
|
||||
}
|
||||
VoiceCliError::Json(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::Daemon(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::UnsupportedFormat(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::FileTooLarge(_) => (StatusCode::PAYLOAD_TOO_LARGE, self.to_string()),
|
||||
VoiceCliError::ModelNotFound(_) => (StatusCode::NOT_FOUND, self.to_string()),
|
||||
VoiceCliError::InvalidModelName(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::WorkerPoolError(_) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, self.to_string())
|
||||
}
|
||||
VoiceCliError::TranscriptionTimeout(_) => {
|
||||
(StatusCode::REQUEST_TIMEOUT, self.to_string())
|
||||
}
|
||||
VoiceCliError::TranscriptionFailed(_) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, self.to_string())
|
||||
}
|
||||
VoiceCliError::AudioConversionFailed(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::AudioProbeError(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::TempFileError(_) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, self.to_string())
|
||||
}
|
||||
VoiceCliError::MultipartError(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::MissingField(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::Network(_) => (StatusCode::BAD_GATEWAY, self.to_string()),
|
||||
VoiceCliError::Storage(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::ConfigRs(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::TaskManagementDisabled(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::NotFound(_) => (StatusCode::NOT_FOUND, self.to_string()),
|
||||
VoiceCliError::Initialization(_) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, self.to_string())
|
||||
}
|
||||
VoiceCliError::TtsError(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
VoiceCliError::InvalidInput(_) => (StatusCode::BAD_REQUEST, self.to_string()),
|
||||
VoiceCliError::Io(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
|
||||
};
|
||||
|
||||
let body = Json(json!({
|
||||
"error": error_message,
|
||||
"status": status.as_u16()
|
||||
}));
|
||||
|
||||
(status, body).into_response()
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, VoiceCliError>;
|
||||
Reference in New Issue
Block a user