openzeppelin_relayer/jobs/handlers/
mod.rs

1use std::sync::Arc;
2
3use apalis::prelude::{Attempt, Error};
4use eyre::Report;
5use tracing::{error, info, warn};
6
7mod transaction_request_handler;
8pub use transaction_request_handler::*;
9
10mod transaction_submission_handler;
11pub use transaction_submission_handler::*;
12
13mod notification_handler;
14pub use notification_handler::*;
15
16mod transaction_status_handler;
17pub use transaction_status_handler::*;
18
19mod solana_swap_request_handler;
20pub use solana_swap_request_handler::*;
21
22mod transaction_cleanup_handler;
23pub use transaction_cleanup_handler::*;
24
25mod relayer_health_check_handler;
26pub use relayer_health_check_handler::*;
27
28pub fn handle_result(
29    result: Result<(), Report>,
30    attempt: Attempt,
31    job_type: &str,
32    max_attempts: usize,
33) -> Result<(), Error> {
34    if result.is_ok() {
35        info!(
36            job_type = %job_type,
37            "request handled successfully"
38        );
39        return Ok(());
40    }
41
42    let err = result.as_ref().unwrap_err();
43    warn!(
44        job_type = %job_type,
45        error = %err,
46        attempt = %attempt.current(),
47        max_attempts = %max_attempts,
48        "request failed"
49    );
50
51    if attempt.current() >= max_attempts {
52        error!(
53            job_type = %job_type,
54            max_attempts = %max_attempts,
55            "max attempts reached, failing job"
56        );
57        Err(Error::Abort(Arc::new("Failed to handle request".into())))?
58    }
59
60    Err(Error::Failed(Arc::new(
61        "Failed to handle request. Retrying".into(),
62    )))?
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68    use apalis::prelude::Attempt;
69
70    #[test]
71    fn test_handle_result_success() {
72        let result: Result<(), Report> = Ok(());
73        let attempt = Attempt::default();
74
75        let handled = handle_result(result, attempt, "test_job", 3);
76        assert!(handled.is_ok());
77    }
78
79    #[test]
80    fn test_handle_result_retry() {
81        let result: Result<(), Report> = Err(Report::msg("Test error"));
82        let attempt = Attempt::default();
83
84        let handled = handle_result(result, attempt, "test_job", 3);
85
86        assert!(handled.is_err());
87        match handled {
88            Err(Error::Failed(_)) => {
89                // This is the expected error type for a retry
90            }
91            _ => panic!("Expected Failed error for retry"),
92        }
93    }
94
95    #[test]
96    fn test_handle_result_abort() {
97        let result: Result<(), Report> = Err(Report::msg("Test error"));
98        let attempt = Attempt::default();
99        for _ in 0..3 {
100            attempt.increment();
101        }
102
103        let handled = handle_result(result, attempt, "test_job", 3);
104
105        assert!(handled.is_err());
106        match handled {
107            Err(Error::Abort(_)) => {
108                // This is the expected error type for an abort
109            }
110            _ => panic!("Expected Abort error for max attempts"),
111        }
112    }
113
114    #[test]
115    fn test_handle_result_max_attempts_exceeded() {
116        let result: Result<(), Report> = Err(Report::msg("Test error"));
117        let attempt = Attempt::default();
118        for _ in 0..5 {
119            attempt.increment();
120        }
121
122        let handled = handle_result(result, attempt, "test_job", 3);
123
124        assert!(handled.is_err());
125        match handled {
126            Err(Error::Abort(_)) => {
127                // This is the expected error type for exceeding max attempts
128            }
129            _ => panic!("Expected Abort error for exceeding max attempts"),
130        }
131    }
132}