1use std::error::Error;
10use std::fmt::{Display, Formatter};
11
12pub type HandlerResult<T> = Result<T, HandlerError>;
14
15#[derive(Clone, Debug, Eq, PartialEq)]
16pub struct HandlerError {
21 message: String,
22 error_type: String,
23}
24
25impl HandlerError {
26 pub fn new(message: impl Into<String>) -> Self {
28 Self {
29 message: message.into(),
30 error_type: std::any::type_name::<Self>().to_string(),
31 }
32 }
33
34 pub(crate) fn invalid_step_result(
35 flow_type: &str,
36 step_type: Option<&str>,
37 method: &str,
38 detail: impl std::fmt::Display,
39 ) -> Self {
40 let target = step_type.map_or_else(
41 || format!("RPC in Flow {flow_type}"),
42 |step_type| format!("Flow {flow_type} Step {step_type}"),
43 );
44 Self {
45 message: format!("{target} {method} returned an invalid result: {detail}"),
46 error_type: "dex_sdk::SdkError::InvalidStepResult".to_string(),
47 }
48 }
49
50 pub(crate) fn error_type(&self) -> &str {
51 &self.error_type
52 }
53}
54
55impl Display for HandlerError {
56 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
57 formatter.write_str(&self.message)
58 }
59}
60
61impl Error for HandlerError {}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn invalid_step_result_has_stable_context_and_type() {
69 let error = HandlerError::invalid_step_result(
70 "OrderFlow",
71 Some("ApproveOrder"),
72 "execute",
73 "missing movement",
74 );
75 assert_eq!("dex_sdk::SdkError::InvalidStepResult", error.error_type());
76 assert!(
77 error
78 .to_string()
79 .contains("Flow OrderFlow Step ApproveOrder")
80 );
81 }
82}