adk-realtime 0.6.0

Real-time bidirectional audio/video streaming for Rust Agent Development Kit (ADK-Rust) agents
Documentation
//! Error types for the realtime module.

use thiserror::Error;

/// Result type for realtime operations.
pub type Result<T> = std::result::Result<T, RealtimeError>;

/// Errors that can occur during realtime operations.
#[derive(Error, Debug)]
pub enum RealtimeError {
    /// WebSocket connection error.
    #[error("WebSocket connection error: {0}")]
    ConnectionError(String),

    /// WebSocket message error.
    #[error("WebSocket message error: {0}")]
    MessageError(String),

    /// Authentication error.
    #[error("Authentication error: {0}")]
    AuthError(String),

    /// Session not connected.
    #[error("Session not connected")]
    NotConnected,

    /// Session already closed.
    #[error("Session already closed")]
    SessionClosed,

    /// Invalid configuration.
    #[error("Invalid configuration: {0}")]
    ConfigError(String),

    /// Audio format error.
    #[error("Audio format error: {0}")]
    AudioFormatError(String),

    /// Tool execution error.
    #[error("Tool execution error: {0}")]
    ToolError(String),

    /// Server returned an error.
    #[error("Server error: {code} - {message}")]
    ServerError {
        /// Error code from the server.
        code: String,
        /// Error message from the server.
        message: String,
    },

    /// Timeout waiting for response.
    #[error("Timeout: {0}")]
    Timeout(String),

    /// Serialization/deserialization error.
    #[error("Serialization error: {0}")]
    SerializationError(#[from] serde_json::Error),

    /// Provider-specific error.
    #[error("Provider error: {0}")]
    ProviderError(String),

    /// Generic IO error.
    #[error("IO error: {0}")]
    IoError(#[from] std::io::Error),

    /// Opus codec error.
    #[error("Opus codec error: {0}")]
    OpusCodecError(String),

    /// WebRTC error.
    #[error("WebRTC error: {0}")]
    WebRTCError(String),

    /// LiveKit bridge error (legacy string format).
    #[error("LiveKit error: {0}")]
    LiveKitError(String),

    /// Native LiveKit component error.
    #[cfg(feature = "livekit")]
    #[error(transparent)]
    LiveKitNativeError(Box<crate::livekit::LiveKitError>),
}

#[cfg(feature = "livekit")]
/// Manually implemented to box the inner error, keeping `Result` small on the happy path.
impl From<crate::livekit::LiveKitError> for RealtimeError {
    fn from(err: crate::livekit::LiveKitError) -> Self {
        RealtimeError::LiveKitNativeError(Box::new(err))
    }
}

impl RealtimeError {
    /// Create a new connection error.
    pub fn connection<S: Into<String>>(msg: S) -> Self {
        Self::ConnectionError(msg.into())
    }

    /// Create a new server error.
    pub fn server<S: Into<String>>(code: S, message: S) -> Self {
        Self::ServerError { code: code.into(), message: message.into() }
    }

    /// Create a new provider error.
    pub fn provider<S: Into<String>>(msg: S) -> Self {
        Self::ProviderError(msg.into())
    }

    /// Create a new configuration error.
    pub fn config<S: Into<String>>(msg: S) -> Self {
        Self::ConfigError(msg.into())
    }

    /// Create a new protocol error.
    pub fn protocol<S: Into<String>>(msg: S) -> Self {
        Self::MessageError(msg.into())
    }

    /// Create a new audio format error.
    pub fn audio<S: Into<String>>(msg: S) -> Self {
        Self::AudioFormatError(msg.into())
    }

    /// Create a new Opus codec error.
    pub fn opus(msg: impl Into<String>) -> Self {
        Self::OpusCodecError(msg.into())
    }

    /// Create a new WebRTC error.
    pub fn webrtc(msg: impl Into<String>) -> Self {
        Self::WebRTCError(msg.into())
    }

    /// Create a new LiveKit error.
    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() {
        // Construct a simple LiveKitError variant
        let inner = crate::livekit::LiveKitError::ConfigError("test config error".to_string());

        // Convert into RealtimeError
        let realtime_err: crate::error::RealtimeError = inner.into();

        // Verify it matches the Boxed variant and formats correctly
        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"),
        }
    }
}