async_utils/hanging_get/
error.rs1use anyhow::format_err;
6use futures::channel::{mpsc, oneshot};
7use thiserror::Error;
8
9#[derive(Error, Debug)]
11pub enum HangingGetServerError {
12 #[error("Cannot have multiple concurrent observers for a single client")]
14 MultipleObservers,
15
16 #[error("The HangingGetBroker associated with this handle has been dropped.")]
18 NoBroker,
19
20 #[error("This handle is sending messages faster than the broker can process them.")]
22 RateLimit,
23
24 #[error("Error: {}", .0)]
26 Generic(anyhow::Error),
27}
28
29impl PartialEq for HangingGetServerError {
30 fn eq(&self, other: &Self) -> bool {
31 use HangingGetServerError::*;
32 match (self, other) {
33 (MultipleObservers, MultipleObservers)
34 | (NoBroker, NoBroker)
35 | (RateLimit, RateLimit) => true,
36 _ => false,
37 }
38 }
39}
40
41impl From<mpsc::SendError> for HangingGetServerError {
42 fn from(error: mpsc::SendError) -> Self {
43 if error.is_disconnected() {
44 HangingGetServerError::NoBroker
45 } else if error.is_full() {
46 HangingGetServerError::RateLimit
47 } else {
48 HangingGetServerError::Generic(format_err!(
49 "Unknown SendError error condition: {}",
50 error
51 ))
52 }
53 }
54}
55
56impl From<oneshot::Canceled> for HangingGetServerError {
57 fn from(e: oneshot::Canceled) -> Self {
58 HangingGetServerError::Generic(e.into())
59 }
60}
61
62impl From<anyhow::Error> for HangingGetServerError {
63 fn from(e: anyhow::Error) -> Self {
65 e.downcast::<mpsc::SendError>().map_or_else(HangingGetServerError::Generic, Self::from)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn error_partial_eq_impl() {
75 use HangingGetServerError::*;
76 let variants = [MultipleObservers, NoBroker, RateLimit, Generic(format_err!("err"))];
77 for (i, a) in variants.iter().enumerate() {
78 for (j, b) in variants.iter().enumerate() {
79 if i == j && i != 3 && j != 3 {
81 assert_eq!(a, b);
82 } else {
83 assert_ne!(a, b);
84 }
85 }
86 }
87 }
88}