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