lmn_core/execution/
error.rs1use tokio::task::JoinError;
2
3#[derive(Debug)]
5pub enum RunError {
6 HttpClientBuild(reqwest::Error),
8 DrainTaskFailed(JoinError),
10}
11
12impl std::fmt::Display for RunError {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 match self {
15 Self::HttpClientBuild(e) => write!(f, "failed to build HTTP client: {e}"),
16 Self::DrainTaskFailed(e) => write!(f, "drain task failed unexpectedly: {e}"),
17 }
18 }
19}
20
21impl std::error::Error for RunError {
22 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
23 match self {
24 Self::HttpClientBuild(e) => Some(e),
25 Self::DrainTaskFailed(e) => Some(e),
26 }
27 }
28}
29
30impl From<reqwest::Error> for RunError {
31 fn from(e: reqwest::Error) -> Self {
32 Self::HttpClientBuild(e)
33 }
34}
35
36impl From<JoinError> for RunError {
37 fn from(e: JoinError) -> Self {
38 Self::DrainTaskFailed(e)
39 }
40}
41
42#[cfg(test)]
45mod tests {
46 use super::*;
47
48 fn make_reqwest_error() -> reqwest::Error {
49 tokio::runtime::Runtime::new()
52 .unwrap()
53 .block_on(reqwest::get("not-a-valid-url"))
54 .unwrap_err()
55 }
56
57 fn make_join_error() -> JoinError {
58 tokio::runtime::Runtime::new().unwrap().block_on(async {
59 tokio::spawn(async { panic!("test panic") })
60 .await
61 .unwrap_err()
62 })
63 }
64
65 #[test]
66 fn display_http_client_build() {
67 let run_err = RunError::HttpClientBuild(make_reqwest_error());
68 assert!(
69 run_err
70 .to_string()
71 .starts_with("failed to build HTTP client:"),
72 "unexpected: {run_err}"
73 );
74 }
75
76 #[test]
77 fn display_drain_task_failed() {
78 let run_err = RunError::DrainTaskFailed(make_join_error());
79 assert!(
80 run_err
81 .to_string()
82 .starts_with("drain task failed unexpectedly:"),
83 "unexpected: {run_err}"
84 );
85 }
86
87 #[test]
88 fn source_is_set() {
89 let run_err = RunError::HttpClientBuild(make_reqwest_error());
90 assert!(
91 std::error::Error::source(&run_err).is_some(),
92 "source must be set"
93 );
94 }
95
96 #[test]
97 fn from_reqwest_error_produces_http_client_build_variant() {
98 let run_err = RunError::from(make_reqwest_error());
99 assert!(matches!(run_err, RunError::HttpClientBuild(_)));
100 }
101
102 #[test]
103 fn from_join_error_produces_drain_task_failed_variant() {
104 let run_err = RunError::from(make_join_error());
105 assert!(matches!(run_err, RunError::DrainTaskFailed(_)));
106 }
107}