1use alloy::primitives::U256;
7use thiserror::Error;
8
9#[derive(Error, Debug)]
11#[non_exhaustive]
12pub enum PerpCityError {
13 #[error("invalid price: {reason}")]
16 InvalidPrice { reason: String },
17
18 #[error("invalid margin: {reason}")]
20 InvalidMargin { reason: String },
21
22 #[error("invalid leverage: {reason}")]
24 InvalidLeverage { reason: String },
25
26 #[error("invalid tick range: lower={lower}, upper={upper}")]
28 InvalidTickRange { lower: i32, upper: i32 },
29
30 #[error("invalid margin ratio: {value} (must be in [{min}, {max}])")]
32 InvalidMarginRatio { value: u32, min: u32, max: u32 },
33
34 #[error("invalid configuration: {reason}")]
36 InvalidConfig { reason: String },
37
38 #[error("arithmetic overflow: {context}")]
41 Overflow { context: String },
42
43 #[error("transaction reverted: {reason}")]
46 TxReverted { reason: String },
47
48 #[error("event not found in receipt: {event_name}")]
50 EventNotFound { event_name: String },
51
52 #[error("gas price unavailable: {reason}")]
54 GasPriceUnavailable { reason: String },
55
56 #[error("too many in-flight transactions: {count} (max {max})")]
58 TooManyInFlight { count: usize, max: usize },
59
60 #[error("perp does not exist: {perp_id}")]
63 PerpNotFound { perp_id: U256 },
64
65 #[error("position does not exist: id={pos_id}")]
67 PositionNotFound { pos_id: U256 },
68
69 #[error("module not registered: {module}")]
71 ModuleNotRegistered { module: String },
72
73 #[error(transparent)]
76 AlloyContract(#[from] alloy::contract::Error),
77
78 #[error(transparent)]
80 AlloyTransport(#[from] alloy::transports::TransportError),
81
82 #[error(transparent)]
84 Serde(#[from] serde_json::Error),
85}
86
87pub type Result<T> = std::result::Result<T, PerpCityError>;
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn serde_error_converts() {
96 let json_err = serde_json::from_str::<String>("not valid json").unwrap_err();
97 let err: PerpCityError = json_err.into();
98 assert!(matches!(err, PerpCityError::Serde(_)));
99 }
100
101 #[test]
102 fn error_is_send_sync() {
103 fn assert_send_sync<T: Send + Sync>() {}
104 assert_send_sync::<PerpCityError>();
105 }
106}