use thiserror::Error;
pub type Result<T> = std::result::Result<T, RealtimeError>;
#[derive(Error, Debug)]
pub enum RealtimeError {
#[error("WebSocket connection error: {0}")]
ConnectionError(String),
#[error("WebSocket message error: {0}")]
MessageError(String),
#[error("Authentication error: {0}")]
AuthError(String),
#[error("Session not connected")]
NotConnected,
#[error("Session already closed")]
SessionClosed,
#[error("Invalid configuration: {0}")]
ConfigError(String),
#[error("Audio format error: {0}")]
AudioFormatError(String),
#[error("Tool execution error: {0}")]
ToolError(String),
#[error("Server error: {code} - {message}")]
ServerError {
code: String,
message: String,
},
#[error("Timeout: {0}")]
Timeout(String),
#[error("Serialization error: {0}")]
SerializationError(#[from] serde_json::Error),
#[error("Provider error: {0}")]
ProviderError(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Opus codec error: {0}")]
OpusCodecError(String),
#[error("WebRTC error: {0}")]
WebRTCError(String),
#[error("LiveKit error: {0}")]
LiveKitError(String),
#[cfg(feature = "livekit")]
#[error(transparent)]
LiveKitNativeError(Box<crate::livekit::LiveKitError>),
}
#[cfg(feature = "livekit")]
impl From<crate::livekit::LiveKitError> for RealtimeError {
fn from(err: crate::livekit::LiveKitError) -> Self {
RealtimeError::LiveKitNativeError(Box::new(err))
}
}
impl RealtimeError {
pub fn connection<S: Into<String>>(msg: S) -> Self {
Self::ConnectionError(msg.into())
}
pub fn server<S: Into<String>>(code: S, message: S) -> Self {
Self::ServerError { code: code.into(), message: message.into() }
}
pub fn provider<S: Into<String>>(msg: S) -> Self {
Self::ProviderError(msg.into())
}
pub fn config<S: Into<String>>(msg: S) -> Self {
Self::ConfigError(msg.into())
}
pub fn protocol<S: Into<String>>(msg: S) -> Self {
Self::MessageError(msg.into())
}
pub fn audio<S: Into<String>>(msg: S) -> Self {
Self::AudioFormatError(msg.into())
}
pub fn opus(msg: impl Into<String>) -> Self {
Self::OpusCodecError(msg.into())
}
pub fn webrtc(msg: impl Into<String>) -> Self {
Self::WebRTCError(msg.into())
}
pub fn livekit(msg: impl Into<String>) -> Self {
Self::LiveKitError(msg.into())
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "livekit")]
#[test]
fn test_livekit_native_error_conversion() {
let inner = crate::livekit::LiveKitError::ConfigError("test config error".to_string());
let realtime_err: crate::error::RealtimeError = inner.into();
match realtime_err {
crate::error::RealtimeError::LiveKitNativeError(boxed_err) => {
assert!(matches!(*boxed_err, crate::livekit::LiveKitError::ConfigError(_)));
assert_eq!(
format!("{}", boxed_err),
"LiveKit configuration error: test config error"
);
}
_ => panic!("Expected LiveKitNativeError variant"),
}
}
}