llm_kit_assemblyai/
error.rs

1use llm_kit_provider::error::ProviderError;
2use serde::{Deserialize, Serialize};
3use thiserror::Error;
4
5/// AssemblyAI-specific error types.
6#[derive(Error, Debug)]
7pub enum AssemblyAIError {
8    /// API error from AssemblyAI
9    #[error("AssemblyAI API error: {message} (code: {code})")]
10    ApiError { message: String, code: i32 },
11
12    /// Network error
13    #[error("Network error: {0}")]
14    NetworkError(#[from] reqwest::Error),
15
16    /// JSON parsing error
17    #[error("JSON parsing error: {0}")]
18    JsonError(#[from] serde_json::Error),
19
20    /// Transcription failed
21    #[error("Transcription failed: {0}")]
22    TranscriptionFailed(String),
23
24    /// Transcription was aborted
25    #[error("Transcription was aborted")]
26    Aborted,
27
28    /// Invalid response from API
29    #[error("Invalid API response: {0}")]
30    InvalidResponse(String),
31
32    /// Upload failed
33    #[error("Upload failed: {0}")]
34    UploadFailed(String),
35}
36
37/// AssemblyAI API error response structure.
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct AssemblyAIErrorResponse {
40    pub error: AssemblyAIErrorDetail,
41}
42
43/// AssemblyAI API error detail.
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct AssemblyAIErrorDetail {
46    pub message: String,
47    pub code: i32,
48}
49
50impl From<AssemblyAIError> for ProviderError {
51    fn from(error: AssemblyAIError) -> Self {
52        match error {
53            AssemblyAIError::ApiError { message, code } => ProviderError::api_call_error(
54                format!("AssemblyAI API error (code {}): {}", code, message),
55                "https://api.assemblyai.com",
56                "",
57            ),
58            AssemblyAIError::NetworkError(e) => ProviderError::api_call_error(
59                format!("Network error: {}", e),
60                "https://api.assemblyai.com",
61                "",
62            ),
63            AssemblyAIError::JsonError(e) => ProviderError::api_call_error(
64                format!("JSON parsing error: {}", e),
65                "https://api.assemblyai.com",
66                "",
67            ),
68            AssemblyAIError::TranscriptionFailed(msg) => ProviderError::api_call_error(
69                format!("Transcription failed: {}", msg),
70                "https://api.assemblyai.com",
71                "",
72            ),
73            AssemblyAIError::Aborted => {
74                ProviderError::api_call_error("Request aborted", "https://api.assemblyai.com", "")
75            }
76            AssemblyAIError::InvalidResponse(msg) => ProviderError::api_call_error(
77                format!("Invalid response: {}", msg),
78                "https://api.assemblyai.com",
79                "",
80            ),
81            AssemblyAIError::UploadFailed(msg) => ProviderError::api_call_error(
82                format!("Upload failed: {}", msg),
83                "https://api.assemblyai.com",
84                "",
85            ),
86        }
87    }
88}
89
90/// Parse an AssemblyAI error response from JSON.
91pub fn parse_error_response(body: &str) -> Result<AssemblyAIError, serde_json::Error> {
92    let error_response: AssemblyAIErrorResponse = serde_json::from_str(body)?;
93    Ok(AssemblyAIError::ApiError {
94        message: error_response.error.message,
95        code: error_response.error.code,
96    })
97}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102
103    #[test]
104    fn test_parse_error_response() {
105        let json = r#"{"error": {"message": "Invalid API key", "code": 401}}"#;
106        let error = parse_error_response(json).unwrap();
107
108        match error {
109            AssemblyAIError::ApiError { message, code } => {
110                assert_eq!(message, "Invalid API key");
111                assert_eq!(code, 401);
112            }
113            _ => panic!("Expected ApiError"),
114        }
115    }
116
117    #[test]
118    fn test_error_to_provider_error() {
119        let error = AssemblyAIError::ApiError {
120            message: "Test error".to_string(),
121            code: 500,
122        };
123
124        let provider_error: ProviderError = error.into();
125        assert!(provider_error.to_string().contains("Test error"));
126    }
127}