use thiserror::Error;
#[derive(Error, Debug)]
pub enum GatewayError {
#[error("Failed to connect to gateway at {url}: {source}")]
ConnectionFailed {
url: String,
#[source]
source: tokio_tungstenite::tungstenite::Error,
},
#[error("Gateway authentication failed")]
AuthenticationFailed,
#[error("Heartbeat timeout - no ACK received")]
HeartbeatTimeout,
#[error("Invalid payload received (opcode {opcode}): {message}")]
InvalidPayload { opcode: u8, message: String },
#[error("WebSocket error: {0}")]
WebSocketError(#[from] tokio_tungstenite::tungstenite::Error),
#[error("Session expired (session_id: {session_id})")]
SessionExpired { session_id: String },
#[error("Failed to parse JSON payload: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Channel send error: {0}")]
ChannelSendError(String),
#[error("Invalid gateway URL: {0}")]
InvalidUrl(#[from] url::ParseError),
#[error("Gateway connection closed unexpectedly")]
ConnectionClosed,
#[error("Invalid Hello payload: {0}")]
InvalidHello(String),
#[error("Missing required field '{field}' in {payload_type} payload")]
MissingField { payload_type: String, field: String },
#[error("Invalid session state: {0}")]
InvalidState(String),
}
pub type Result<T> = std::result::Result<T, GatewayError>;
impl<T> From<async_channel::SendError<T>> for GatewayError {
fn from(err: async_channel::SendError<T>) -> Self {
GatewayError::ChannelSendError(err.to_string())
}
}