rvoip_transaction_core/
error.rs1use crate::transaction::{TransactionKey, TransactionKind, TransactionState};
2use std::io;
3use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, Error>;
7
8#[derive(Error, Debug)]
10pub enum Error {
11 #[error("SIP core error: {0}")]
13 SipCoreError(#[from] rvoip_sip_core::Error),
14
15 #[error("SIP transport error: {source}")]
17 TransportError {
18 #[source]
19 source: TransportErrorWrapper,
20 context: Option<String>,
21 },
22
23 #[error("Transaction not found: {key} (context: {context})")]
25 TransactionNotFound {
26 key: TransactionKey,
27 context: String,
28 },
29
30 #[error("Transaction already exists: {key} (kind: {kind:?})")]
32 TransactionExists {
33 key: TransactionKey,
34 kind: TransactionKind,
35 },
36
37 #[error("Invalid state transition: {from_state:?} -> {to_state:?} for {transaction_kind:?} transaction")]
39 InvalidStateTransition {
40 transaction_kind: TransactionKind,
41 from_state: TransactionState,
42 to_state: TransactionState,
43 transaction_id: Option<TransactionKey>,
44 },
45
46 #[error("Transaction timed out: {key} (timer: {timer})")]
48 TransactionTimeout {
49 key: TransactionKey,
50 timer: String,
51 },
52
53 #[error("Timer error: {message}")]
55 TimerError {
56 message: String,
57 },
58
59 #[error("I/O error: {0}")]
61 Io(#[from] io::Error),
62
63 #[error("Channel error: {context}")]
65 ChannelError {
66 context: String,
67 },
68
69 #[error("Failed to create transaction: {message}")]
71 TransactionCreationError {
72 message: String,
73 },
74
75 #[error("Failed to process message: {message} for transaction {transaction_id:?}")]
77 MessageProcessingError {
78 message: String,
79 transaction_id: Option<TransactionKey>,
80 },
81
82 #[error("Transport management error: {0}")]
84 Transport(String),
85
86 #[error("Other error: {0}")]
88 Other(String),
89}
90
91#[derive(Debug)]
93pub struct TransportErrorWrapper(pub String);
94
95impl std::fmt::Display for TransportErrorWrapper {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 write!(f, "{}", self.0)
98 }
99}
100
101impl std::error::Error for TransportErrorWrapper {}
102
103impl From<rvoip_sip_transport::Error> for Error {
105 fn from(e: rvoip_sip_transport::Error) -> Self {
106 Error::TransportError {
107 source: TransportErrorWrapper(e.to_string()),
108 context: None,
109 }
110 }
111}
112
113impl From<&str> for Error {
114 fn from(s: &str) -> Self {
115 Error::Other(s.to_string())
116 }
117}
118
119impl From<String> for Error {
120 fn from(s: String) -> Self {
121 Error::Other(s)
122 }
123}
124
125impl<T> From<tokio::sync::mpsc::error::SendError<T>> for Error {
127 fn from(e: tokio::sync::mpsc::error::SendError<T>) -> Self {
128 Error::ChannelError {
129 context: format!("Send error: channel closed while sending {:?}", std::any::type_name::<T>()),
130 }
131 }
132}
133
134impl Error {
136 pub fn transaction_not_found(key: TransactionKey, context: impl Into<String>) -> Self {
138 Error::TransactionNotFound {
139 key,
140 context: context.into(),
141 }
142 }
143
144 pub fn transport_error(source: rvoip_sip_transport::Error, context: impl Into<String>) -> Self {
146 Error::TransportError {
147 source: TransportErrorWrapper(source.to_string()),
148 context: Some(context.into()),
149 }
150 }
151
152 pub fn invalid_state_transition(
154 transaction_kind: TransactionKind,
155 from_state: TransactionState,
156 to_state: TransactionState,
157 transaction_id: Option<TransactionKey>,
158 ) -> Self {
159 Error::InvalidStateTransition {
160 transaction_kind,
161 from_state,
162 to_state,
163 transaction_id,
164 }
165 }
166
167 pub fn channel_error(context: impl Into<String>) -> Self {
169 Error::ChannelError {
170 context: context.into(),
171 }
172 }
173
174 pub fn transaction_timeout(key: TransactionKey, timer: impl Into<String>) -> Self {
176 Error::TransactionTimeout {
177 key,
178 timer: timer.into(),
179 }
180 }
181}