hopr_transport/path/
errors.rs1use std::sync::Arc;
2
3use hopr_api::types::internal::errors::PathError;
4
5pub type Result<T> = std::result::Result<T, PathPlannerError>;
6
7#[derive(thiserror::Error, Debug)]
9pub enum PathPlannerError {
10 #[error("path error: {0}")]
11 Path(#[from] PathError),
12
13 #[error("{0}")]
14 Other(#[from] anyhow::Error),
15
16 #[error("surb: {0}")]
17 Surb(String),
18
19 #[error("api: {0}")]
20 Api(String),
21
22 #[error("cache error: {0}")]
23 CacheError(#[from] Arc<Self>),
24}
25
26impl PathPlannerError {
27 pub fn is_surb(&self) -> bool {
32 match self {
33 PathPlannerError::Surb(_) => true,
34 PathPlannerError::CacheError(inner) => inner.is_surb(),
35 _ => false,
36 }
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn is_surb_detects_direct_and_cache_wrapped() {
46 let direct = PathPlannerError::Surb("no surb".into());
47 assert!(direct.is_surb(), "direct Surb must be detected");
48
49 let wrapped = PathPlannerError::CacheError(Arc::new(PathPlannerError::Surb("no surb".into())));
52 assert!(wrapped.is_surb(), "cache-wrapped Surb must be detected");
53
54 let nested = PathPlannerError::CacheError(Arc::new(wrapped));
55 assert!(nested.is_surb(), "doubly cache-wrapped Surb must be detected");
56
57 let other = PathPlannerError::Api("unrelated".into());
58 assert!(
59 !other.is_surb(),
60 "non-Surb error must not be treated as SURB starvation"
61 );
62 assert!(
63 !PathPlannerError::CacheError(Arc::new(other)).is_surb(),
64 "cache-wrapped non-Surb error must not be treated as SURB starvation"
65 );
66 }
67}